在 SWT/JFace 開發中,管理多個視窗是常見需求。無論是啟動多個主視窗,還是彈出模態對話框讓使用者互動,掌握 Shell 的建立、配置與事件迴圈處理至關重要。本文透過兩個完整範例,示範如何建立多個獨立視窗,以及如何實作一個帶有單選按鈕的模態對話框並將結果回傳給主視窗。
第一個範例展示如何在單一 Display 下建立兩個 Shell,並分別設定不同尺寸的圖示(16×16 與 32×32)。程式透過 GC 繪製簡單圖形作為圖示,隨後呼叫 shell.open() 顯示視窗,最後進入標準的事件分派迴圈。
Display display = new Display();
Image small = new Image(display, 16, 16);
GC gc = new GC(small);
gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
gc.fillArc(0, 0, 16, 16, 45, 270);
gc.dispose();
Image large = new Image(display, 32, 32);
gc = new GC(large);
gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
gc.fillArc(0, 0, 32, 32, 45, 270);
gc.dispose();
Shell shell = new Shell(display);
shell.setText("Small and Large icons");
shell.setImages(new Image[] {small, large});
Shell shell2 = new Shell(display);
shell2.setText("Small icon");
shell2.setImage(small);
shell.open();
shell2.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
關鍵點:
Display 可管理多個 Shell。setImages(Image[]) 可一次設定多種尺寸圖示,系統會自動選擇最適合的尺寸。shell.isDisposed() 為終止條件;若需等待所有視窗關閉,可自行維護計數器。第二個範例建立一個主視窗,點擊按鈕後彈出 SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL 風格的對話框。對話框包含一組單選按鈕與「確認」按鈕,使用者選擇評分後關閉對話框,主視窗按鈕文字即時更新為所選評分。
final Shell dialog = new Shell(shell, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
dialog.setLayout(new RowLayout());
final String[] ratings = {"Killer!", "Good stuff", "So-so", "Needs work"};
final Button[] radios = new Button[ratings.length];
for (int i = 0; i < ratings.length; i++) {
radios[i] = new Button(dialog, SWT.RADIO);
radios[i].setText(ratings[i]);
}
Button rateButton = new Button(dialog, SWT.PUSH);
rateButton.setText("Rate!");
rateButton.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
for (int i = 0; i < radios.length; i++)
if (radios[i].getSelection())
openDialog.setText("Rating: " + ratings[i]);
dialog.close();
}
public void widgetDefaultSelected(SelectionEvent e) {}
});
dialog.pack();
// 置中顯示
Rectangle shellBounds = shell.getBounds();
Point dialogSize = dialog.getSize();
dialog.setLocation(
shellBounds.x + (shellBounds.width - dialogSize.x) / 2,
shellBounds.y + (shellBounds.height - dialogSize.y) / 2
);
dialog.open();
關鍵點:
SWT.APPLICATION_MODAL 限制使用者必須先關閉對話框才能操作主視窗。dialog.pack() 依元件建議尺寸自動調整對話框大小。shell.getBounds() 與 dialog.getSize() 計算置中座標,提升使用者體驗。Display,主視窗繼續執行原有事件迴圈。Image、GC、Display 必須在適當時機呼叫 dispose(),避免記憶體洩漏。Dialog 類別(JFace)封裝邏輯,而非直接操作 Shell。本文示範了 SWT 中多視窗與模態對話框的核心技巧:建立多個 Shell、設定圖示、事件迴圈控制、對話框置中與資料回傳。掌握這些基礎,即可構建出具備良好互動體驗的桌面應用程式。