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() {
@Override
public BasicSplitPaneDivider createDefaultDivider() {
return new BasicSplitPaneDivider(this) {
@Override
public 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() {
@Override
public 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() { @Override public BasicSplitPaneDivider createDefaultDivider() { return new BasicSplitPaneDivider(this) { @Override public 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;
@Override
public void actionPerformed(ActionEvent e) {
tabbedPane.addTab("标签" + tabCount, new JLabel("新标签页 " + tabCount));
tabCount++;
}
});
// 删除标签按钮事件
removeButton.addActionListener(new ActionListener() {
@Override
public 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 中组织多页面界面的高效组件,通过标签切换可有效节省屏幕空间。其核心优势在于支持多种标签布局、动态操作和自定义样式,适用于需要分类展示内容