2011-03-24 34 views
0

我有一個用SWT編寫的大型現有應用程序,我不得不修改。在SWT中,父shell和非對話子shell之間進行通信的最佳方式是什麼?

GUI包含在打開非對話框的子shell中。

現在我必須在關閉子shell時更新父shell的信息。

我想象中的兩個選項:

  1. 轉換所有的孩子來擴展對話框類。問題是它需要大量的重構。
  2. 傳遞父邏輯類的引用,以便在關閉子元素之前,我可以調用父類的方法。我不喜歡這種設計。

這將是很好,如果在父代碼中,我可以監聽子shell事件並根據子shell上發生的事情采取行動。這是一種可觀察的模式。我在「SWT:開發者筆記本」中讀到:

ChildShell不需要任何事件循環。爲什麼?因爲父shell的事件循環處理爲在父代中打開的所有對象分派事件。孩子一直處於打開狀態,直到用戶關閉或直到父母關閉。

我沒有在SWT中進行實驗,實例很少。那麼SWT的做法是什麼?我可以爲此目的使用父循環嗎?

謝謝。

回答

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變量中,然後使用該字符串變量來填充父項文本框。

+1

非常感謝它的魅力。實際上我需要一個DisposeListener。感謝您的回覆,我向SWT邁出了一大步。 – 2011-03-24 12:50:01

相關問題