首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

SWT/JFace StackLayout 佈局管理:單一顯示區域的多控件切換技巧

     編輯:Java 相關知識

StackLayout 核心機制

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();
    }
}

關鍵 API 與注意事項

1. 核心屬性:topControl

型別為 Control。設定此屬性後,必須呼叫父容器的 layout() 方法,佈局管理器才會重新計算並切換顯示內容。

2. 子控件生命週期

  • 所有加入 Shell/Composite 的子控件會被 StackLayout 管理,無論是否為 topControl,皆會佔用記憶體並保持實例化狀態。
  • 若頁面數量極大或包含重資源控件(如 Browser、大型 Table),建議改用 TabFolder 或動態 dispose()/create 控件以節省資源。

3. 邊距與間距

StackLayout 不支援 marginWidth、marginHeight、spacing 等屬性。子控件會填滿父容器客戶區。若需邊距,請在子控件內部自行處理(如外層包一層 Composite 設定 FillLayout + margin)。

進階應用模式:搭配 ToolBar 或 List 導航

實務上常搭配側邊導航列(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() 這組核心組合,即可靈活應用於各種動態介面切換需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved