SWT 调整大小错误

SWT Resize Error

我一直在使用 SWT 并发现了一个问题。

选中和取消选中复选框并最大化 window 时,即使第一个按钮为空,也会设置其图标。按钮上的文本布局也可能最终不正确。

重现错误:

  1. Select 复选框 1
  2. 取消选中复选框 1
  3. Select 复选框 3
  4. 最大化window

复选框 1 的图标应为 null(空),但它有十字图标。

  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();
   }

这无论如何都不理想,但如果您需要解决方法,您可以尝试包装 Button 并使用 StackLayout 在启用的 [=12= 之间切换] 和一个残疾人 Button。这样你就不是 adding/removing Image。这也解决了布局问题,因为实际的 Button 实例没有改变状态。

例如:

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;
    }

}

同样,这并不理想,但您始终可以将方法(addListener(...) 等)添加到 MyButton class 以调用启用的 [=12] 上的方法=],现在只是一个实现细节。

对您的 main 方法的更改:

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());
        }
    });

    // ...

}

结果:(请注意,我只更改了第一个按钮