在SWT中,父shell和非对话子shell之间进行通信的最佳方式是什么?

时间:2011-03-24 05:32:04

标签: java shell swt communication

我有一个用SWT编写的大型现有应用程序,我必须修改。

GUI包含打开非Dialog子shell的shell。

现在,我必须在子shell关闭时更新父shell的信息。

我想到了两个选择:

  1. 将所有子项转换为扩展Dialog类。问题是它需要大量重构。
  2. 传递父逻辑类的引用,以便在关闭子类之前,我可以调用父类的方法。我不喜欢这种设计。
  3. 如果在父代码中我可以监听子shell事件并根据子shell上发生的事情采取行动,那将是很好的。这是一种可观察的模式。我在“SWT:开发笔记本”中读到了:

      

    ChildShell不需要事件循环。为什么?因为父shell的事件循环处理为父内部打开的所有对象调度事件。孩子在用户关闭或父母关闭之前一直保持开放状态。

    我没有在SWT中进行过实验,例子很少。那么SWT的做法是什么?我可以将父循环用于此目的吗?

    感谢。

1 个答案:

答案 0 :(得分:4)

我建议你在子shell上使用ShellListener。然后,您可以覆盖shellClosed方法。

示例

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class Test {

    private static Text text;

    public static void main (String [] args) 
    {
        Display display = new Display ();
        final Shell shell = new Shell (display);
        shell.setLayout(new GridLayout());
        shell.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        shell.setSize(200, 100);
        shell.setText("Parent Shell");

        Label label = new Label(shell, SWT.NONE);
        label.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        label.setText("The text from child shell ...");

        text = new Text(shell, SWT.BORDER);
        text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

        Button openChild = new Button(shell, SWT.PUSH);
        openChild.setText("Open Child ...");
        openChild.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                openChild(shell);
            }
        });

        shell.open ();

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

    private static void openChild(Shell parent)
    {
        final Shell dialog = new Shell (parent, SWT.DIALOG_TRIM);
        dialog.setLayout(new GridLayout());
        dialog.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        dialog.setSize(200, 100);
        dialog.setText("Child Shell");

        Label childLabel = new Label(dialog, SWT.NONE);
        childLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
        childLabel.setText("Type something here ...");

        final Text childText = new Text(dialog, SWT.BORDER);
        childText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));

        Button okButton = new Button (dialog, SWT.PUSH);
        okButton.setText ("&OK");
        okButton.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                dialog.close();
            }
        });


        dialog.addShellListener(new ShellListener() {
            public void shellIconified(ShellEvent e) {
            }
            public void shellDeiconified(ShellEvent e) {
            }
            public void shellDeactivated(ShellEvent e) {
            }
            public void shellClosed(ShellEvent e) {
                if(text != null && !text.isDisposed())
                    text.setText(childText.getText());
            }
            public void shellActivated(ShellEvent e) {
            }
        });


        dialog.setDefaultButton (okButton);
        dialog.open ();
    }
} 

注意

您也可以使用DisposeListener,但在这种情况下,您无法使用text.setText(childText.getText());(请参阅上面的示例)。要处理此问题,请将文本保存在String变量中,然后使用字符串变量填充父文本框。