SWT 提供兩種分割控件:
建立一個垂直 Sash,監聽 SWT.Selection,事件物件 Event 包含建議的新位置 e.x, e.y, e.width, e.height,直接套用至 Sash 自身 bounds。
package swt_jface.demo9;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.swt.widgets.Shell;
public class SashExample {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
final Sash sash = new Sash(shell, SWT.BORDER | SWT.VERTICAL);
sash.setBounds(10, 10, 15, 60); // 初始位置與大小 (寬15像素)
sash.addListener(SWT.Selection, e -> {
System.out.println("Selected. " + e.x + "," + e.y);
// 關鍵:將事件建議的矩形套用回 Sash
sash.setBounds(e.x, e.y, e.width, e.height);
// 實務上這裡需同步調整左側/右側控件的 bounds
});
shell.open();
sash.setFocus(); // 獲得焦點以接收鍵盤事件 (若支援)
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
}
注意:此範例僅展示 Sash 本身移動。實際應用中,必須在 Listener 中根據
e.x重新計算並setBounds左側與右側的 Composite/Control,否則分割條移動但內容不跟隨。
展示水平 SashForm 包含三個面板 (Text, Text, 垂直 SashForm),設定權重 1:2:3。巢狀垂直 SashForm 示範雙擊 Label 最大化/還原功能。
package swt_jface.demo9;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.layout.FillLayout;
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 SashFormExample {
Display display = new Display();
Shell shell = new Shell(display);
SashForm sashForm, sashForm2;
public SashFormExample() {
shell.setLayout(new FillLayout());
// 主水平分割
sashForm = new SashForm(shell, SWT.HORIZONTAL);
Text text1 = new Text(sashForm, SWT.CENTER | SWT.BORDER);
text1.setText("Text in pane #1");
Text text2 = new Text(sashForm, SWT.CENTER | SWT.BORDER);
text2.setText("Text in pane #2");
// 巢狀垂直分割 (放在第3個位置)
sashForm2 = new SashForm(sashForm, SWT.VERTICAL);
final Label labelA = new Label(sashForm2, SWT.BORDER | SWT.CENTER);
labelA.setText("Label in pane A");
final Label labelB = new Label(sashForm2, SWT.BORDER | SWT.CENTER);
labelB.setText("Label in pane B");
// 監聽尺寸變化 (除錯用)
text1.addControlListener(new ControlListener() {
public void controlMoved(ControlEvent e) {}
public void controlResized(ControlEvent e) {
System.out.println("Resized. Weights: " + java.util.Arrays.toString(sashForm.getWeights()));
}
});
// 設定初始權重:Pane1:Pane2:Pane3 = 1:2:3
sashForm.setWeights(new int[]{1, 2, 3});
// 雙擊 Label 最大化/還原該面板
labelA.addMouseListener(new MouseListener() {
public void mouseDoubleClick(MouseEvent e) {
if (sashForm2.getMaximizedControl() == labelA)
sashForm2.setMaximizedControl(null); // 還原
else
sashForm2.setMaximizedControl(labelA); // 最大化佔滿 sashForm2
}
public void mouseDown(MouseEvent e) {}
public void mouseUp(MouseEvent e) {}
});
shell.setSize(450, 200);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
public static void main(String[] args) {
new SashFormExample();
}
}
new SashForm(parent, SWT.HORIZONTAL) // 左右分割,Sash 垂直
new SashForm(parent, SWT.VERTICAL) // 上下分割,Sash 水平
setWeights(int[]):設定各面板相對寬度/高度比例。總和不需為 100,如 {1, 2, 3} 表示 1/6, 2/6, 3/6。getWeights():取得目前比例 (使用者拖曳後會更新)。sashForm.setWeights(newWeights); sashForm.layout();。setMaximizedControl(Control):指定控件佔滿整個 SashForm 空間,其他控件隱藏。Sash 暫時消失。getMaximizedControl():取得目前最大化控件,null 代表正常模式。SashForm 實作 Layout 介面。父容器若用 FillLayout,SashForm 會填滿父容器。子控件無需設定 LayoutData,SashForm 依權重自動計算 bounds。
記住使用者調整的分割比例,下次啟動還原:
// 關閉視窗前儲存
prefs.putInt("sashWeight1", sashForm.getWeights()[0]);
prefs.putInt("sashWeight2", sashForm.getWeights()[1]);
// 啟動時還原
int[] weights = { prefs.getInt("sashWeight1", 1), prefs.getInt("sashWeight2", 2) };
sashForm.setWeights(weights);
SWT.HORIZONTAL/VERTICAL) 且子控件數量 ≥ 2。setMaximizedControl(null)。ControlListener 或自訂 SashForm (繼承覆寫 computeSize),但較複雜。通常靠 UI 設計避免 (如 ToolBar 最小寬度)。SashForm 是構建可調整大小分割介面的標準選擇。它封裝了繁瑣的幾何計算,提供權重、最大化、巢狀分割等豐富功能。僅在需要極度客製化分割條外觀 (如自訂圖形、顏色、吸附行為) 時,才考慮直接使用原生 Sash 並自行管理佈局邏輯。