Reputation: 4341
I've been using SWT and have found an issue.
When selecting and deselecting check boxes and maximizing the window it will cause the icon of the first button to be set even though it is null. Also the layout of the text on the buttons can end up incorrect.
To recreate the error:
The icon for checkbox 1 should be null (empty) but instead it has the cross icon.
public static void main(String[] args) {
final Display d = new Display();
Shell s = new Shell(d);
s.setLayout(new GridLayout(2, false));
s.setSize(500, 500);
new Label(s, SWT.NONE).setText("C");
final Button c = new Button(s, SWT.CHECK);
new Label(s, SWT.NONE).setText("L1");
final Button b = new Button(s, SWT.PUSH | SWT.FLAT);
b.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
b.setText("Button 1");
b.setEnabled(false);
new Label(s, SWT.NONE).setText("C2");
final Button c2 = new Button(s, SWT.CHECK);
new Label(s, SWT.NONE).setText("L2");
final Button b2 = new Button(s, SWT.PUSH | SWT.FLAT);
b2.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
b2.setImage(null);
b2.setText("Button 2");
b2.setEnabled(false);
new Label(s, SWT.NONE).setText("C3");
final Button c3 = new Button(s, SWT.CHECK);
new Label(s, SWT.NONE).setText("L3");
final Button b3 = new Button(s, SWT.PUSH | SWT.FLAT);
b3.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
b3.setText("Button 3");
b3.setEnabled(false);
c.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (!b.isEnabled()) {
b.setImage(d.getSystemImage(SWT.ICON_ERROR));
b.setEnabled(true);
} else {
b.setImage(null);
b.setEnabled(false);
}
}
});
c2.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (!b2.isEnabled()) {
b2.setImage(d.getSystemImage(SWT.ICON_ERROR));
b2.setEnabled(true);
} else {
b2.setImage(null);
b2.setEnabled(false);
}
}
});
c3.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (!b3.isEnabled()) {
b3.setImage(d.getSystemImage(SWT.ICON_ERROR));
b3.setEnabled(true);
} else {
b3.setImage(null);
b3.setEnabled(false);
}
}
});
s.open();
while (!s.isDisposed()) {
if (!d.readAndDispatch())
d.sleep();
}
d.dispose();
}
Upvotes: 4
Views: 169
Reputation: 2360
This isn't ideal by any means, but if you need a workaround, one thing you could try is wrapping Button
and using a StackLayout
to flip between an enabled Button
and a disabled Button
. That way you're not adding/removing the Image
. This also fixes the layout issues because the actual Button
instances are not changing state.
For example:
public static class MyButton {
private final Button buttonEnabled;
private final Button buttonDisabled;
private final Composite stackComposite;
private final StackLayout stackLayout;
public MyButton(final Composite parent, final String text) {
stackComposite = new Composite(parent, SWT.NONE);
stackLayout = new StackLayout();
stackComposite.setLayout(stackLayout);
stackComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
buttonEnabled = createButton(stackComposite, text, true);
buttonDisabled = createButton(stackComposite, text, false);
stackLayout.topControl = buttonEnabled;
}
public void setEnabled(final boolean enabled) {
stackLayout.topControl = enabled ? buttonEnabled : buttonDisabled;
stackComposite.layout();
}
public boolean isEnabled() {
return stackLayout.topControl.equals(buttonEnabled) ? true : false;
}
private static Button createButton(final Composite parent,
final String text, final boolean enabled) {
final Button button = new Button(parent, SWT.PUSH | SWT.FLAT);
button.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
button.setText(text);
button.setEnabled(enabled);
if (enabled) {
button.setImage(parent.getDisplay().getSystemImage(SWT.ICON_ERROR));
}
return button;
}
}
Again, this isn't ideal, but you can always add methods (addListener(...)
, etc.) to the MyButton
class to call methods on the enabled Button
, which is now just an implementation detail.
Changes to your main
method:
public static void main(final String[] args) {
// ...
new Label(s, SWT.NONE).setText("C");
final Button c = new Button(s, SWT.CHECK);
new Label(s, SWT.NONE).setText("L1");
final MyButton b = new MyButton(s, "Button 1");
// ...
c.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
b.setEnabled(!b.isEnabled());
}
});
// ...
}
Result: (note that I only changed the first button)
Upvotes: 1