org.eclipse.swt.custom.StackLayout 是一種特殊的佈局管理器,它將所有子控件疊放在同一位置,同一時間僅顯示一個控件(topControl)。這非常適合實作「精靈嚮導步驟」、「標籤頁切換」或「狀態面板切換」等場景,且不需像 TabFolder 那樣自帶標籤 UI。
此範例建立三個 Button,點擊任一按鈕即切換顯示下一個按鈕,形成循環。
package swt_jface.demo2;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class StackLayoutSample {
Display display = new Display();
Shell shell = new Shell(display);
final Button[] buttons = new Button[3];
public StackLayoutSample() {
final StackLayout stackLayout = new StackLayout();
shell.setLayout(stackLayout);
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new Button(shell, SWT.NULL);
buttons[i].setText("Button #" + i);
buttons[i].addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
Button nextButton = null;
// 找出目前被點擊的按鈕索引
for (int i = 0; i < buttons.length; i++) {
if (buttons[i] == e.widget) {
// 循環邏輯:最後一個回到第一個
if (i == buttons.length - 1)
nextButton = buttons[0];
else
nextButton = buttons[i + 1];
}
}
// 核心:設定 topControl 並重新佈局
stackLayout.topControl = nextButton;
shell.layout(); // 必須呼叫 layout() 才會生效
}
public void widgetDefaultSelected(SelectionEvent e) {}
});
}
// 初始顯示第一個按鈕
stackLayout.topControl = buttons[0];
shell.setSize(200, 100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
public static void main(String[] args) {
new StackLayoutSample();
}
}
型別為 Control。設定此屬性後,必須呼叫父容器的 layout() 方法,佈局管理器才會重新計算並切換顯示內容。
TabFolder 或動態 dispose()/create 控件以節省資源。StackLayout 不支援 marginWidth、marginHeight、spacing 等屬性。子控件會填滿父容器客戶區。若需邊距,請在子控件內部自行處理(如外層包一層 Composite 設定 FillLayout + margin)。
實務上常搭配側邊導航列(List/Tree/ToolBar)使用:
// 導航列選擇事件
navList.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
int index = navList.getSelectionIndex();
if (index >= 0 && index < pages.length) {
stackLayout.topControl = pages[index];
parent.layout(true); // true 表示遞迴佈局子控件
}
}
});
StackLayout 以極簡 API 實現「單顯示區多內容切換」,適合輕量級 UI 狀態切換。掌握 topControl + layout() 這組核心組合,即可靈活應用於各種動態介面切換需求。