Swt Expandlistener Executes Before Collapse Occurs on Linux

SWT ExpandListener executes before collapse occurs on Linux

I am unhappy with this solution but it works.

Definitely a XXX solution

Use XXX in a comment to flag something that is bogus but works. Use FIXME to flag something that is bogus and broken.
- java.sun.com

without further ado

import org.eclipse.swt.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.events.ExpandEvent;
import org.eclipse.swt.events.ExpandListener;

public class ExpandBarExample {
public static void main(String[] args) {
Shell shell = new Shell(SWT.DIALOG_TRIM | SWT.MIN
| SWT.APPLICATION_MODAL);
shell.setLayout(new FormLayout());
shell.setText("Expand Bar");
final ExpandBar bar = new ExpandBar(shell, SWT.NONE);
FormData fd = new FormData();
fd.top = new FormAttachment(0);
fd.left = new FormAttachment(0);
fd.right = new FormAttachment(100);
fd.bottom = new FormAttachment(100);
bar.setLayoutData(fd);

bar.addExpandListener(new ExpandListener() {

private void resize(final ExpandEvent event, final boolean expand){

final Display display = Display.getCurrent();

new Thread(new Runnable() {
public void run() {

final int[] orgSize = new int[1];
final int[] currentSize = new int[1];

final Object lock = new Object();

if (display.isDisposed() || bar.isDisposed()){
return;
}

display.syncExec(new Runnable() {
public void run() {
if (bar.isDisposed() || bar.getShell().isDisposed()){
return;
}

synchronized(lock){
bar.getShell().pack(true);
orgSize[0] = bar.getShell().getSize().y;
currentSize[0] = orgSize[0];
}
}
});

while (currentSize[0] == orgSize[0]){
if (display.isDisposed() || bar.isDisposed()){
return;
}

display.syncExec(new Runnable() {
public void run() {

synchronized(lock){
if (bar.isDisposed() || bar.getShell().isDisposed()){
return;
}

currentSize[0] = bar.getShell().getSize().y;

if (currentSize[0] != orgSize[0]){
return;
}
else{
bar.getShell().layout(true);
bar.getShell().pack(true);
}
}
}
});
}
}
}).start();
}

public void itemCollapsed(ExpandEvent event) {
resize(event, false);
}

public void itemExpanded(ExpandEvent event) {
resize(event, true);
}

});

Composite composite = new Composite(bar, SWT.NONE);
fd = new FormData();
fd.left = new FormAttachment(0);
fd.right = new FormAttachment(100);
composite.setLayoutData(fd);

FormLayout layout = new FormLayout();
layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 8;

composite.setLayout(layout);
Label label = new Label(composite, SWT.NONE);
label.setText("This is Bar 1");
ExpandItem item1 = new ExpandItem(bar, SWT.NONE, 0);
item1.setText("Bar 1");
item1.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
item1.setControl(composite);
item1.setExpanded(true);

composite = new Composite(bar, SWT.NONE);
fd = new FormData();
fd.left = new FormAttachment(0);
fd.right = new FormAttachment(100);
composite.setLayoutData(fd);

layout = new FormLayout();
layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 8;
composite.setLayout(layout);
label = new Label(composite, SWT.NONE);
label.setText("This is Bar2");
ExpandItem item2 = new ExpandItem(bar, SWT.NONE, 1);
item2.setText("Bar 2");
item2.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
item2.setControl(composite);
item2.setExpanded(true);

composite = new Composite(bar, SWT.NONE);
fd = new FormData();
fd.left = new FormAttachment(0);
fd.right = new FormAttachment(100);
composite.setLayoutData(fd);

layout = new FormLayout();
layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 8;
composite.setLayout(layout);
label = new Label(composite, SWT.NONE);
label.setText("This is Bar3");
ExpandItem item3 = new ExpandItem(bar, SWT.NONE, 2);
item3.setText("Bar 3");
item3.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
item3.setControl(composite);
item3.setExpanded(true);

bar.setSpacing(6);
shell.pack();
shell.open();
Display display = shell.getDisplay();

while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}

}

If anyone wants to know what this is doing and doesn't want to look at the code.

Basically the ExpandListener looks at the original height of the shell, and issues syncExec's to pack() the shell until the shell actually changes size. A very busy waiting approach.

ExpandBar works incorrectly with GridLayout

I get it working, but I'm not satisfied with this solution...

bar.addExpandListener(new ExpandAdapter() {

@Override
public void itemCollapsed(ExpandEvent e) {
new Thread(new Runnable() {

@Override
public void run() {
try {
synchronized (this) {
wait(250);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Display.getDefault().asyncExec(new Runnable() {
public void run() {
layout();

}
});
}
}).start();
}

@Override
public void itemExpanded(ExpandEvent e) {
new Thread(new Runnable() {

@Override
public void run() {
try {
synchronized (this) {
wait(250);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Display.getDefault().asyncExec(new Runnable() {
public void run() {
layout();

}
});
}
}).start();
}
});

Why do newly created elements in a Java SWT Selection listener not get displayed/trigger a paint event?

If you using layout, you should call Composite.layout() (or layout(true)) after add a new child to composite.
Layout do not know (so do not places widget) until you call layout().

By the way, if you resize the shell(composite), layout automatically invalidates its internal caches and checks all the children, places them. that's why newly created text appears after you resized the shell.

Seeking useful Eclipse Java code templates

The following code templates will both create a logger and create the right imports, if needed.

SLF4J

${:import(org.slf4j.Logger,org.slf4j.LoggerFactory)}
private static final Logger LOG = LoggerFactory.getLogger(${enclosing_type}.class);

Log4J 2

${:import(org.apache.logging.log4j.LogManager,org.apache.logging.log4j.Logger)} 
private static final Logger LOG = LogManager.getLogger(${enclosing_type}.class);

Log4J

${:import(org.apache.log4j.Logger)}
private static final Logger LOG = Logger.getLogger(${enclosing_type}.class);

Source.

JUL

${:import(java.util.logging.Logger)}
private static final Logger LOG = Logger.getLogger(${enclosing_type}.class.getName());


Related Topics



Leave a reply



Submit