
本教程详细介绍了如何在java swing的jtable中实现行颜色的持久化更改。针对jtable默认选中颜色无法保持的问题,文章提出通过在数据模型中引入一个不可见的布尔列来存储行选中状态,并结合自定义的tablecellrenderer根据此状态渲染行背景色,同时利用鼠标监听器动态更新模型数据,从而实现选中行颜色在取消选择后依然保持的效果。
在Java Swing应用程序开发中,JTable是一个常用的组件,用于显示和编辑表格数据。然而,JTable默认的行选择行为是临时的:当用户点击一行时,该行会高亮显示,但一旦选择其他行或表格失去焦点,之前的行就会恢复默认颜色。如果我们需要实现选中行颜色持久化,即使用户取消选择或选择其他行,特定行的颜色依然保持不变,就需要进行一些定制化开发。
本文将深入探讨如何通过扩展JTable的数据模型、自定义单元格渲染器以及事件监听器来达到这一目的。核心思路是为每一行引入一个“选中”状态标记,并让渲染器根据这个标记来绘制行的背景色。
要实现JTable行颜色的持久化,我们需要协同以下三个关键组件:
首先,我们需要在DefaultTableModel中添加一个额外的列来存储行的选中状态。这个列将是一个布尔类型,初始值设为false。为了不影响用户界面,这个列在JTable的视图中将被隐藏。
立即学习“Java免费学习笔记(深入)”;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumnModel;
import javax.swing.JTable;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import javax.swing.JScrollPane;
// ... 其他导入
@SuppressWarnings("serial")
class ChangeRowColorPanel extends JPanel {
private static final String[] COLUMN_NAMES = { "One", "Two", "Three", "Selected" };
private DefaultTableModel model = new DefaultTableModel(COLUMN_NAMES, 0);
private JTable table = new JTable(model);
public ChangeRowColorPanel() {
// 隐藏最后一列("Selected"列)
TableColumnModel columnModel = table.getColumnModel();
// columnModel.getColumnCount() - 1 获取最后一列的索引
columnModel.removeColumn(columnModel.getColumn(columnModel.getColumnCount() - 1));
// 设置自定义渲染器
table.setDefaultRenderer(Object.class, new RowColorRenderer());
// 添加鼠标监听器
table.addMouseListener(new MyMouse());
// 填充一些示例数据
int max = 5;
for (int i = 0; i < max; i++) {
Object[] row = new Object[COLUMN_NAMES.length];
for (int j = 0; j < COLUMN_NAMES.length - 1; j++) {
row[j] = (int) (100 * Math.random());
}
row[COLUMN_NAMES.length - 1] = false; // 初始状态为未选中
model.addRow(row);
}
setLayout(new BorderLayout());
add(new JScrollPane(table));
}
}在ChangeRowColorPanel的构造函数中:
TableCellRenderer负责绘制JTable中的每个单元格。我们将创建一个继承自DefaultTableCellRenderer的自定义渲染器,并在其getTableCellRendererComponent方法中,根据数据模型中“Selected”列的值来设置行的背景色。
import java.awt.Color;
import java.awt.Component;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableModel;
@SuppressWarnings("serial")
class RowColorRenderer extends DefaultTableCellRenderer {
private static final Color SELECTED_COLOR = Color.PINK; // 定义选中行的颜色
public RowColorRenderer() {
setOpaque(true); // 必须设置为true,否则背景色可能不显示
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
// 调用父类方法获取默认的渲染组件
Component renderer = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
TableModel model = table.getModel();
int selectedColumn = model.getColumnCount() - 1; // 获取“Selected”列的索引
// 从模型中获取当前行的“Selected”状态
boolean selected = (boolean) model.getValueAt(row, selectedColumn);
// 根据状态设置背景色
Color background = selected ? SELECTED_COLOR : null; // 如果选中,则为粉色,否则为默认
renderer.setBackground(background);
// 返回当前渲染器自身,因为我们直接修改了它的背景色
return this;
}
}在RowColorRenderer中:
我们需要一个事件监听器来捕获用户点击表格的动作。当用户点击一行时,我们应该切换该行在数据模型中“Selected”状态,并通知表格重新绘制。
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JTable;
import javax.swing.table.TableModel;
class MyMouse extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
JTable table = (JTable) e.getSource();
TableModel model = table.getModel();
int selectedRow = table.getSelectedRow(); // 获取当前点击的行索引
if (selectedRow == -1) { // 如果没有选中行,则直接返回
return;
}
// 获取当前行的“Selected”状态
boolean selected = (boolean) model.getValueAt(selectedRow, model.getColumnCount() - 1);
// 切换状态
model.setValueAt(!selected, selectedRow, model.getColumnCount() - 1);
table.repaint(); // 通知表格重新绘制,以应用新的颜色
}
}在MyMouse中:
将以上组件整合到一个主应用程序中:
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class TestTableRowColor {
public static void main(String[] args) {
// 确保Swing组件在事件调度线程中创建和更新
SwingUtilities.invokeLater(() -> {
ChangeRowColorPanel mainPanel = new ChangeRowColorPanel();
JFrame frame = new JFrame("JTable行颜色持久化示例");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack(); // 根据组件的首选大小调整窗口
frame.setLocationRelativeTo(null); // 窗口居中显示
frame.setVisible(true); // 显示窗口
});
}
}TestTableRowColor类负责创建JFrame,并将ChangeRowColorPanel添加到其中,然后显示窗口。SwingUtilities.invokeLater确保所有Swing相关的操作都在事件调度线程(Event Dispatch Thread, EDT)上执行,这是Swing编程的最佳实践。
通过上述方法,我们成功地实现了JTable行颜色的持久化功能,极大地提升了用户体验和界面的交互性。这种模式不仅限于颜色,还可以应用于其他需要持久化行状态的场景,例如标记已处理的行、特殊状态的行等。
以上就是Java JTable:通过自定义渲染器和数据模型实现行颜色持久化的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号