java - 在运行时设置 JTable 行的颜色
问题描述
我的 Java 8 小程序连接到 SQL 数据库,并在JTable
包含两列的 a 中显示“选择”语句的结果:
如果第 1 行/ColumnA 中的字符串与第 0 行/ColumnA 中的字符串不同,我想给第 1 行一个灰色背景色(以标记“新”数据的开始),其他行应该使用默认白色。
创建表的代码:
JTable myTable = new JTable();
myTable.setSelectionModel(new ToggleListSelectionModel()); //custom selection model
myTable.setModel(new DefaultTableModel(
new Object[][] {
},
new String[] {
"ColumnA", "ColumnB"
}
));
获取数据并填写表格:
Statement stat = connection.createStatement();
ResultSet rs = stat.executeQuery(someSelectStatement);
Object[] row = null;
while(rs.next()) {
int columns = rs.getMetaData().getColumnCount();
row = new Object[columns];
for (int i=1; i<=columns; i++) {
row[i - 1] = rs.getObject(i);
}
//TODO: Set color of row according to data in "ColumnA" of previous row
((DefaultTableModel) myTable.getModel()).insertRow(rs.getRow()-1,row); //Add new row with the ResultSet's content
//Get String data of ColumnA for this specific row with e.g. "(String) row[0]"
}
rs.close();
stat.close();
从我目前发现的情况来看,我必须使用自定义TableModel
而不是DefaultTableModel
我在开始时设置的,但我该如何使用它呢?我发现的所有东西都使用固定检查,例如
如果单元格中的内容是“购买”,则将背景颜色设置为“绿色”
(例如here或here)但在我的情况下,我对创建表时的内容一无所知,因为它是在运行时填充/行添加的。
我也找到了这个答案,但是问题的作者读取了数据,然后更改了模型,然后才填充表格,而我逐行填充表格(直接在读取行的内容之后)。
我的问题:我知道如何将单元格的内容与上一行中单元格的内容进行比较,但是如何在运行时设置该行的背景颜色?
编辑:
这是一些用于填写表格的 MRE 代码。请注意:如果您发布有关如何完成我想做的事情的建议,请记住我正在使用数据库和ResultSet
(参见上面的代码),而不是预定义的数据(参见下面的代码)!
JTable myTable = new JTable();
myTable.setSelectionModel(new ToggleListSelectionModel()); //custom selection model
myTable.setModel(new DefaultTableModel(
new Object[][] {
{"1000", 123},
{"1000", 234},
{"1001", 123},
{"1002", 123},
{"1002", 234},
{"1002", 345},
{"1003", 123},
{"1003", 234}
},
new String[] {
"ColumnA", "ColumnB"
}
));
结果:
所需结果(每个新“A 列”值的灰色背景):
替代结果(替代标记组的所有行):
解决方案
table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
Component comp = super.getTableCellRendererComponent(table,
value, isSelected, hasFocus, row, column);
if(!isSelected) { //Important check, see comment below!
boolean levelBreak = row == 0;
if (!levelBreak) {
Object prior = table.getValueAt(row - 1, 0);
Object current = table.getValueAt(row, 0);
levelBreak = !prior.equals(current);
}
comp.setBackground(levelBreak ? Color.BLUE : Color.WHITE);
}
return comp;
}
});
由于渲染器/渲染器组件对所有表格单元格重复使用,因此必须为所有情况设置背景。
一般来说,JTable 的 TabelModel 比 JTable 的 getValueAt 更适合获取值,但显然您既不排序行也不重新排列列。
对于可能安装的较旧渲染器
class MyCellRenderer extends DefaultTableCellRenderer {
private final TableCellRenderer old;
MyCellRenderer(TableCellRenderer old) {
this.old = old;
}
@Override
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
boolean levelBreak = row == 0;
if (!levelBreak) {
Object prior = table.getValueAt(row - 1, 0);
Object current = table.getValueAt(row, 0);
levelBreak = !prior.equals(current);
}
Component comp;
if (old != null) {
comp = old.getTableCellRendererComponent(table,
value, isSelected, hasFocus, row, column);
} else {
comp = super.getTableCellRendererComponent(table,
value, isSelected, hasFocus, row, column);
}
comp.setBackground(levelBreak ? Color.BLUE : Color.WHITE);
return comp;
}
}
table.setDefaultRenderer(Object.class, new MyCellRenderer(table.getDefaultRenderer(Object.class));
推荐阅读
- javascript - 如何:使用 websocket 的 MS Bot 直接消息传递
- java - 使用 Java LocalTime 锁定下溢/上溢
- python - django.core.exceptions.ImproperlyConfigured:找不到 GDAL 库
- python - 无法从 txt 文件制作字典
- reactjs - 更新 reactjs 中的嵌套状态
- android - Android:测试蓝牙启用意图(Espresso-Intents Instrumented Test)
- amazon-web-services - 使用 Amazon ECR 集群 - 每个微服务一个或每个微服务驻留在一个服务上
- r - 提高上传速度以在 r 中表现出色
- python - Django 数据库:如何根据其他对象的字段过滤对象?
- javascript - 如何计算两个连续数组元素的最高乘积?