SWT StackLayout topControl 显然不工作

SWT StackLayout topControl apparently not working

我正在测试一个简单的 SWT StackLayout 示例以了解它是如何工作的,但事情并没有像我预期的那样工作。

我创建了一个带有两个按钮的 StackLayout,两个按钮都设置为在它们被选中时在两个按钮之间循环五次顶部控件,每次顶部控件更改时暂停 2 秒。然而,当我 运行 这个问题时,我没有看到任何事情发生。

关于我遗漏的任何想法?

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;


public class MyApp {

    protected Shell shlMyFirstSwt;
    Button btnOne;
    Button btnTwo;

    /**
     * Launch the application.
     * @param args
     */
    public static void main(String[] args) {
        try {
            MyApp window = new MyApp();
            window.open();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Open the window.
     */
    public void open() {
        Display display = Display.getDefault();
        createContents();
        shlMyFirstSwt.open();
        shlMyFirstSwt.layout();
        while (!shlMyFirstSwt.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }

    /**
     * Create contents of the window.
     * @throws InterruptedException 
     */
    protected void createContents() {
        shlMyFirstSwt = new Shell();
        shlMyFirstSwt.setSize(621, 416);
        shlMyFirstSwt.setText("My First SWT Application");
        StackLayout layout = new StackLayout();
        shlMyFirstSwt.setLayout(layout);

        Button btnOne = new Button(shlMyFirstSwt, SWT.NONE);
        btnOne.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                for (int i = 0; i != 10; i++) {
                    layout.topControl = i % 2 == 0? btnOne : btnTwo;
                    shlMyFirstSwt.layout();
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });
        btnOne.setText("One");

        Button btnTwo = new Button(shlMyFirstSwt, SWT.NONE);
        btnTwo.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                for (int i = 0; i != 10; i++) {
                    layout.topControl = i % 2 == 0? btnOne : btnTwo;
                    shlMyFirstSwt.layout();
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });
        btnTwo.setText("Two");
    }
}

第一个答案后的详细说明:

立即尝试更简单的方法。现在我修改了事件处理程序,让一个按钮将顶部控件切换为另一个按钮,如下所示。我希望这两个按钮交替作为顶部控件,但是当我单击第一个按钮时,window 变为空白。知道为什么吗?

        Button btnOne = new Button(shlMyFirstSwt, SWT.NONE);
        btnOne.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                layout.topControl = btnTwo;
                shlMyFirstSwt.layout();
            }
        });
        btnOne.setText("One");

        Button btnTwo = new Button(shlMyFirstSwt, SWT.NONE);
        btnTwo.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                layout.topControl = btnOne;
                shlMyFirstSwt.layout();
            }
        });
        btnTwo.setText("Two");

您的 Thread.sleep 调用阻塞了用户界面线程,因此 GUI 无法更新。您绝不能像这样阻塞用户界面线程。对 layout 等方法的调用不会立即更新 - 它们需要 display.readAndDispatch 运行以分派生成的各种更新。

如果你想延迟使用 Display.timerExec:

Display.getDefault().timerExec(2000, new Runnable() {
   @Override
   public void run()
   {
     ... code to be run after the delay
   }
});

因此您必须重新编写代码才能使用它来进行定时更新。

搞清楚了:这只是在初始化之前将 btnTwo 包含在第一个事件处理程序中的愚蠢错误,即使它在初始化后使用