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 中组织多页面界面的高效组件,通过标签切换可有效节省屏幕空间。其核心优势在于支持多种标签布局、动态操作和自定义样式,适用于需要分类展示内容