JSplitPane
JSplitPane
?是 Java Swing 中用于創建分隔面板的組件,支持兩個可調整大小組件的容器。它允許用戶通過拖動分隔條來調整兩個組件的相對大小,適合用于需要動態調整視圖比例的場景。
- 常用方法:
setLeftComponent(Component comp)
:設置左側組件。setRightComponent(Component comp)
?或?setBottomComponent(Component comp)
:根據方向設置另一側組件。setDividerLocation(int location)
:設置分割條的位置。
1. 基本概念與特點
- 分隔方向:支持水平分隔(
HORIZONTAL_SPLIT
)和垂直分隔(VERTICAL_SPLIT
)。 - 子組件:只能包含兩個組件(左 / 右或上 / 下),通過?
setLeftComponent()
、setRightComponent()
?或?setTopComponent()
、setBottomComponent()
?設置。 - 分隔條(Divider):可自定義寬度、顏色和樣式,支持拖動調整大小。
- 連續布局:拖動分隔條時是否實時更新布局(
setContinuousLayout(true)
)。 - 一鍵折疊:支持通過?
setOneTouchExpandable(true)
?添加快速折疊按鈕。
2. 常用構造方法
構造方法 | 描述 |
---|---|
JSplitPane() | 創建默認水平分隔的面板,使用?FlowLayout ,無初始組件。 |
JSplitPane(int orientation) | 指定分隔方向(HORIZONTAL_SPLIT ?或?VERTICAL_SPLIT )。 |
JSplitPane(int orientation, boolean continuousLayout) | 指定分隔方向和是否啟用連續布局。 |
JSplitPane(int orientation, Component leftComponent, Component rightComponent) | 指定分隔方向和初始子組件。 |
3. 核心方法
方法 | 描述 |
---|---|
setDividerLocation(double proportionalLocation) | 設置分隔條位置(0.0~1.0 表示比例)。 |
setDividerLocation(int location) | 設置分隔條的絕對位置(像素值)。 |
setDividerSize(int newSize) | 設置分隔條的寬度。 |
setOneTouchExpandable(boolean newValue) | 啟用 / 禁用一鍵折疊功能。 |
setContinuousLayout(boolean newContinuousLayout) | 啟用 / 禁用連續布局(拖動時分隔條是否實時更新)。 |
setLeftComponent(Component comp) ?/?setTopComponent(Component comp) | 設置左側 / 頂部組件。 |
setRightComponent(Component comp) ?/?setBottomComponent(Component comp) | 設置右側 / 底部組件。 |
4. 簡單示例:水平分隔面板
import javax.swing.*;
import java.awt.*;public class JSplitPaneExample {public static void main(String[] args) {JFrame frame = new JFrame("JSplitPane 示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(600, 400);// 創建左側面板(列表)JList<String> list = new JList<>(new String[]{"項目1", "項目2", "項目3", "項目4"});JScrollPane leftPanel = new JScrollPane(list);// 創建右側面板(文本區域)JTextArea textArea = new JTextArea("這是右側面板內容...");JScrollPane rightPanel = new JScrollPane(textArea);// 創建水平分隔面板JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, // 水平分隔leftPanel, // 左側組件rightPanel // 右側組件);// 設置分隔條初始位置(比例)splitPane.setDividerLocation(0.3);// 啟用一鍵折疊功能splitPane.setOneTouchExpandable(true);// 啟用連續布局splitPane.setContinuousLayout(true);frame.add(splitPane);frame.setVisible(true);}
}
5. 嵌套分隔面板示例
通過嵌套?JSplitPane
?可創建復雜的布局:
import javax.swing.*;
import java.awt.*;public class NestedSplitPaneExample {public static void main(String[] args) {JFrame frame = new JFrame("嵌套 JSplitPane 示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(800, 600);// 創建頂部面板(文本區域)JTextArea topTextArea = new JTextArea("這是頂部面板...");JScrollPane topPanel = new JScrollPane(topTextArea);// 創建左側面板(列表)JList<String> leftList = new JList<>(new String[]{"選項1", "選項2", "選項3"});JScrollPane leftPanel = new JScrollPane(leftList);// 創建右側上部面板(表格)String[] columnNames = {"ID", "名稱"};Object[][] data = {{1, "項目A"}, {2, "項目B"}, {3, "項目C"}};JTable table = new JTable(data, columnNames);JScrollPane rightTopPanel = new JScrollPane(table);// 創建右側下部面板(文本區域)JTextArea bottomTextArea = new JTextArea("這是底部面板...");JScrollPane rightBottomPanel = new JScrollPane(bottomTextArea);// 創建右側垂直分隔面板JSplitPane rightSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,rightTopPanel,rightBottomPanel);rightSplitPane.setDividerLocation(0.5);// 創建主水平分隔面板JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,leftPanel,rightSplitPane);mainSplitPane.setDividerLocation(0.3);// 創建最終的垂直分隔面板(頂部面板和主分隔面板)JSplitPane finalSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,topPanel,mainSplitPane);finalSplitPane.setDividerLocation(0.2);frame.add(finalSplitPane);frame.setVisible(true);}
}
6. 自定義分隔條樣式
通過設置?UI
?屬性或子類化?BasicSplitPaneUI
?可自定義分隔條外觀:
import javax.swing.*;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import java.awt.*;public class CustomDividerExample {public static void main(String[] args) {JFrame frame = new JFrame("自定義分隔條示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(600, 400);JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,new JLabel("左側面板"),new JLabel("右側面板"));// 自定義分隔條樣式splitPane.setUI(new BasicSplitPaneUI() {@Overridepublic BasicSplitPaneDivider createDefaultDivider() {return new BasicSplitPaneDivider(this) {@Overridepublic void paint(Graphics g) {// 繪制自定義分隔條g.setColor(Color.RED);g.fillRect(0, 0, getSize().width, getSize().height);super.paint(g);}};}});// 設置分隔條寬度splitPane.setDividerSize(10);frame.add(splitPane);frame.setVisible(true);}
}
7. 監聽分隔條位置變化
通過?PropertyChangeListener
?監聽?dividerLocation
?屬性變化:
import javax.swing.*;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;public class DividerListenerExample {public static void main(String[] args) {JFrame frame = new JFrame("分隔條監聽示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(600, 400);JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,new JLabel("左側面板"),new JLabel("右側面板"));// 添加分隔條位置變化監聽器splitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, new PropertyChangeListener() {@Overridepublic void propertyChange(PropertyChangeEvent e) {System.out.println("分隔條位置變化:" + e.getOldValue() + " -> " + e.getNewValue());}});frame.add(splitPane);frame.setVisible(true);}
}
8. 注意事項
- 組件大小:
JSplitPane
?會根據子組件的首選大小初始化分隔條位置,可通過?setPreferredSize()
?調整。 - 禁用拖動:通過重寫?
Divider
?的?mouseDragged()
?方法可禁用分隔條拖動:splitPane.setUI(new BasicSplitPaneUI() {@Overridepublic BasicSplitPaneDivider createDefaultDivider() {return new BasicSplitPaneDivider(this) {@Overridepublic void mouseDragged(java.awt.event.MouseEvent e) {// 空實現,禁用拖動}};} });
- 持久化分隔條位置:可通過?
getDividerLocation()
?獲取當前位置,并在下次啟動時通過?setDividerLocation()
?恢復。
JSplitPane
?是 Java Swing 中創建動態分隔界面的強大組件,通過簡單配置即可實現靈活的布局。其核心優勢在于支持嵌套結構、實時調整和自定義樣式,適用于需要動態分配空間的應用場景(如編輯器、文件管理器等)。
JTabbedPane
JTabbedPane
?是 Java Swing 中用于創建選項卡式界面的組件?提供了一個選項卡式的界面,允許用戶通過點擊不同的選項卡來切換內容視圖。每個選項卡可以包含不同的組件或信息,非常適合用于多頁面的應用程序界面。
- 常用方法:
addTab(String title, Component component)
:添加一個新的選項卡。setSelectedIndex(int index)
:選擇指定索引處的選項卡。setTitleAt(int index, String title)
:設置指定索引處選項卡的標題。
1. 基本概念與特點
- 選項卡布局:支持頂部、底部、左側或右側放置標簽。
- 標簽樣式:可自定義標簽文本、圖標和工具提示。
- 組件關聯:每個標簽對應一個組件(如?
JPanel
、JTextArea
?等)。 - 動態操作:支持添加、刪除和重排序標簽。
- 事件監聽:可監聽標簽切換事件。
2. 常用構造方法
構造方法 | 描述 |
---|---|
JTabbedPane() | 創建默認標簽位于頂部的選項卡面板。 |
JTabbedPane(int tabPlacement) | 指定標簽位置(TOP 、BOTTOM 、LEFT 、RIGHT )。 |
JTabbedPane(int tabPlacement, int tabLayoutPolicy) | 指定標簽位置和布局策略(WRAP_TAB_LAYOUT ?或?SCROLL_TAB_LAYOUT )。 |
3. 核心方法
方法 | 描述 |
---|---|
addTab(String title, Component component) | 添加帶標題的標簽頁。 |
addTab(String title, Icon icon, Component component) | 添加帶標題和圖標的標簽頁。 |
addTab(String title, Icon icon, Component component, String tip) | 添加帶標題、圖標和工具提示的標簽頁。 |
insertTab(String title, Icon icon, Component component, String tip, int index) | 在指定位置插入標簽頁。 |
removeTabAt(int index) | 移除指定位置的標簽頁。 |
setSelectedIndex(int index) | 選擇指定索引的標簽頁。 |
setTabComponentAt(int index, Component component) | 設置標簽的自定義組件(如帶關閉按鈕的標簽)。 |
setTitleAt(int index, String title) | 修改指定標簽的標題。 |
setIconAt(int index, Icon icon) | 修改指定標簽的圖標。 |
addChangeListener(ChangeListener listener) | 添加標簽切換事件監聽器。 |
4. 簡單示例:基本選項卡面板
import javax.swing.*;
import java.awt.*;public class JTabbedPaneExample {public static void main(String[] args) {JFrame frame = new JFrame("JTabbedPane 示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(600, 400);// 創建選項卡面板JTabbedPane tabbedPane = new JTabbedPane();// 添加第一個標簽頁JPanel panel1 = new JPanel();panel1.add(new JLabel("這是第一個標簽頁"));tabbedPane.addTab("標簽1", panel1);// 添加第二個標簽頁(帶圖標)JPanel panel2 = new JPanel();panel2.add(new JLabel("這是第二個標簽頁"));Icon icon = new ImageIcon("path/to/icon.png"); // 替換為實際圖標路徑tabbedPane.addTab("標簽2", icon, panel2, "這是第二個標簽的提示");// 添加第三個標簽頁JPanel panel3 = new JPanel();panel3.add(new JLabel("這是第三個標簽頁"));tabbedPane.addTab("標簽3", panel3);frame.add(tabbedPane);frame.setVisible(true);}
}
5. 標簽位置與布局策略示例
import javax.swing.*;
import java.awt.*;public class TabPlacementExample {public static void main(String[] args) {JFrame frame = new JFrame("標簽位置示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(800, 600);// 創建一個大的選項卡面板,包含四個方向的標簽子面板JTabbedPane mainTabbedPane = new JTabbedPane();// 頂部標簽JTabbedPane topTabs = new JTabbedPane(JTabbedPane.TOP);topTabs.addTab("頂部1", new JLabel("頂部標簽1"));topTabs.addTab("頂部2", new JLabel("頂部標簽2"));mainTabbedPane.addTab("頂部標簽", topTabs);// 底部標簽JTabbedPane bottomTabs = new JTabbedPane(JTabbedPane.BOTTOM);bottomTabs.addTab("底部1", new JLabel("底部標簽1"));bottomTabs.addTab("底部2", new JLabel("底部標簽2"));mainTabbedPane.addTab("底部標簽", bottomTabs);// 左側標簽JTabbedPane leftTabs = new JTabbedPane(JTabbedPane.LEFT);leftTabs.addTab("左側1", new JLabel("左側標簽1"));leftTabs.addTab("左側2", new JLabel("左側標簽2"));mainTabbedPane.addTab("左側標簽", leftTabs);// 右側標簽JTabbedPane rightTabs = new JTabbedPane(JTabbedPane.RIGHT);rightTabs.addTab("右側1", new JLabel("右側標簽1"));rightTabs.addTab("右側2", new JLabel("右側標簽2"));mainTabbedPane.addTab("右側標簽", rightTabs);frame.add(mainTabbedPane);frame.setVisible(true);}
}
6. 動態操作與事件監聽
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;public class DynamicTabExample {public static void main(String[] args) {JFrame frame = new JFrame("動態選項卡示例");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(600, 400);JTabbedPane tabbedPane = new JTabbedPane();// 添加初始標簽頁tabbedPane.addTab("標簽1", new JLabel("初始標簽頁"));// 創建操作面板JPanel controlPanel = new JPanel();JButton addButton = new JButton("添加標簽");JButton removeButton = new JButton("刪除當前標簽");controlPanel.add(addButton);controlPanel.add(removeButton);// 添加標簽按鈕事件addButton.addActionListener(new ActionListener() {private int tabCount = 2;@Overridepublic void actionPerformed(ActionEvent e) {tabbedPane.addTab("標簽" + tabCount, new JLabel("新標簽頁 " + tabCount));tabCount++;}});// 刪除標簽按鈕事件removeButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {int selectedIndex = tabbedPane.getSelectedIndex();if (selectedIndex >= 0) {tabbedPane.removeTabAt(selectedIndex);}}});// 添加標簽切換監聽器tabbedPane.addChangeListener(e -> {int selectedIndex = tabbedPane.getSelectedIndex();if (selectedIndex >= 0) {System.out.println("切換到標簽:" + tabbedPane.getTitleAt(selectedIndex));}});// 使用 BorderLayout 添加組件frame.getContentPane().add(tabbedPane, BorderLayout.CENTER);frame.getContentPane().add(controlPanel, BorderLayout.SOUTH);frame.setVisible(true);}
}
7. 自定義標簽組件(帶關閉按鈕)
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;public class ClosableTabExample {public static void main(String[] args) {JFrame frame = new JFrame("帶關閉按鈕的標簽");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(600, 400);JTabbedPane tabbedPane = new JTabbedPane();// 添加初始標簽頁addClosableTab(tabbedPane, "標簽1", new JLabel("內容 1"));addClosableTab(tabbedPane, "標簽2", new JLabel("內容 2"));frame.add(tabbedPane);frame.setVisible(true);}private static void addClosableTab(JTabbedPane tabbedPane, String title, Component content) {// 添加標簽頁tabbedPane.addTab(title, content);// 獲取標簽索引int index = tabbedPane.indexOfTab(title);// 創建自定義標簽組件(帶文本和關閉按鈕)JPanel tabComponent = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));tabComponent.setOpaque(false);JLabel titleLabel = new JLabel(title);tabComponent.add(titleLabel);JButton closeButton = new JButton("×");closeButton.setBorder(null);closeButton.setContentAreaFilled(false);closeButton.setFocusPainted(false);closeButton.setMargin(new Insets(0, 0, 0, 0));closeButton.addActionListener(e -> tabbedPane.remove(index));tabComponent.add(closeButton);// 設置自定義標簽組件tabbedPane.setTabComponentAt(index, tabComponent);}
}
8. 注意事項
-
布局策略:當標簽過多時,可使用?
SCROLL_TAB_LAYOUT
?啟用滾動:JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
-
鍵盤導航:默認支持?
Ctrl+Tab
?和?Ctrl+Shift+Tab
?切換標簽,可通過?setMnemonicAt()
?設置快捷鍵。 -
標簽圖標:圖標應保持簡潔,避免過大影響布局。
-
預加載與懶加載:
- 預加載:在初始化時創建所有標簽頁的組件。
- 懶加載:在首次切換到標簽頁時創建組件(通過監聽?
ChangeListener
?實現)。
JTabbedPane
?是 Java Swing 中組織多頁面界面的高效組件,通過標簽切換可有效節省屏幕空間。其核心優勢在于支持多種標簽布局、動態操作和自定義樣式,適用于需要分類展示內容