JTable 单元格渲染器使用其他单元格背景设置背景
JTable cell renderer set backround using other cells background
我有一个 JTable
自定义 cell renderer
以在有新章节在线时突出显示该单元格。
默认TableCellRenderer:
static class CustomRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component cellComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
double valueAt = (double) table.getValueAt(row, column);
double compareValue = (double) table.getValueAt(row, column - 1);
if (compareValue < valueAt) {
cellComponent.setBackground(Color.green);
} else {
Component tableCellRendererComponent = super.getTableCellRendererComponent(table, compareValue, isSelected, hasFocus, row, column - 1);
// Component tableCellRendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column - 1);
// Component tableCellRendererComponent = super.getTableCellRendererComponent(table, valueAt, isSelected, hasFocus, row, column - 1);
Color background = tableCellRendererComponent.getBackground();
cellComponent.setBackground(background);
}
return cellComponent;
}
}
Table 型号:
private String[] columnsGetNewest = {"Current Chapter", "Chapter Online"};
private DefaultTableModel dataModelGetNewest = new DefaultTableModel(columnsGetNewest, 0);
它的应用使用:
tableGetNewest.setModel(dataModelGetNewest);
TableColumn column = tableGetNewest.getColumnModel().getColumn(1);
column.setCellRenderer(new CustomRenderer());
想要的结果:
但由于某些原因,它没有按预期工作:
代码进入 else 分支时似乎可以正常工作。
如果我注释掉 //cellComponent.setBackground(Color.green);
结果如下:
我的代码有什么问题?我怎样才能得到想要的结果?
如果我没理解错的话,您正试图将 Green
右列中比左列中的单元格具有更高值的所有单元格。如果我错了,请纠正。
问题出在您的 TableCellRenderer
上。在以下部分:
if (compareValue < valueAt) {
cellComponent.setBackground(Color.green);
} else {
Component tableCellRendererComponent = super.getTableCellRendererComponent(table, compareValue, isSelected, hasFocus, row, column - 1);
// Component tableCellRendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column - 1);
// Component tableCellRendererComponent = super.getTableCellRendererComponent(table, valueAt, isSelected, hasFocus, row, column - 1);
Color background = tableCellRendererComponent.getBackground();
cellComponent.setBackground(background);
}
我认为解释你做错了什么的最好方法是举个例子。假设在左列中右边的值高于左边的值,所以你的 if
发生并且 renderer
的背景变成 green
。现在,让我们渲染第 2 行。右边的值小于左边的值,因此 if
不会发生。你猜怎么着?您在前一行渲染中将其设为绿色,因此它保持 green
。这就是为什么他们一直保持绿色。如果你把它转一次,你不恢复它,它会留给其他人。
现在,您正在尝试恢复背景super.getTableCellRendererComponent(table, valueAt, isSelected, hasFocus, row, column - 1);
。这是错误的,因为这个方法不是简单的 getter。它还对 table(渲染器)进行了更改。为另一个 row/column 值调用此方法将不起作用。
为了使其正常工作,您必须根据来自 DefaultTableCellRenderer
的默认值恢复它。一个完整的例子:
public class Example extends JFrame {
private static final long serialVersionUID = 811854316682851407L;
private static final String[] COLUMNS = { "Current Chapter", "Chapter Online" };
public Example() {
super("test");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JTable table = new JTable(data(), COLUMNS);
table.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (c instanceof JLabel) {
JLabel renderer = (JLabel) c;
int valueAt = (int) table.getValueAt(row, column);
int compareValue = (int) table.getValueAt(row, column - 1);
if (compareValue < valueAt) {
renderer.setBackground(Color.GREEN);
} else {
if (isSelected)
renderer.setBackground(table.getSelectionBackground());
else {
renderer.setBackground(table.getBackground());
}
}
}
return c;
}
});
JScrollPane sp = new JScrollPane(table);
add(sp);
pack();
setLocationRelativeTo(null);
}
private Object[][] data() {
Object[][] data = { { 113, 444 }, { 233, 555 }, { 110, 92 }, { 55, 66 }, { 123, 603 }, { 412, 120 }, };
return data;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Example().setVisible(true));
}
}
预览:
我有一个 JTable
自定义 cell renderer
以在有新章节在线时突出显示该单元格。
默认TableCellRenderer:
static class CustomRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component cellComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
double valueAt = (double) table.getValueAt(row, column);
double compareValue = (double) table.getValueAt(row, column - 1);
if (compareValue < valueAt) {
cellComponent.setBackground(Color.green);
} else {
Component tableCellRendererComponent = super.getTableCellRendererComponent(table, compareValue, isSelected, hasFocus, row, column - 1);
// Component tableCellRendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column - 1);
// Component tableCellRendererComponent = super.getTableCellRendererComponent(table, valueAt, isSelected, hasFocus, row, column - 1);
Color background = tableCellRendererComponent.getBackground();
cellComponent.setBackground(background);
}
return cellComponent;
}
}
Table 型号:
private String[] columnsGetNewest = {"Current Chapter", "Chapter Online"};
private DefaultTableModel dataModelGetNewest = new DefaultTableModel(columnsGetNewest, 0);
它的应用使用:
tableGetNewest.setModel(dataModelGetNewest);
TableColumn column = tableGetNewest.getColumnModel().getColumn(1);
column.setCellRenderer(new CustomRenderer());
想要的结果:
但由于某些原因,它没有按预期工作:
代码进入 else 分支时似乎可以正常工作。
如果我注释掉 //cellComponent.setBackground(Color.green);
结果如下:
我的代码有什么问题?我怎样才能得到想要的结果?
如果我没理解错的话,您正试图将 Green
右列中比左列中的单元格具有更高值的所有单元格。如果我错了,请纠正。
问题出在您的 TableCellRenderer
上。在以下部分:
if (compareValue < valueAt) {
cellComponent.setBackground(Color.green);
} else {
Component tableCellRendererComponent = super.getTableCellRendererComponent(table, compareValue, isSelected, hasFocus, row, column - 1);
// Component tableCellRendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column - 1);
// Component tableCellRendererComponent = super.getTableCellRendererComponent(table, valueAt, isSelected, hasFocus, row, column - 1);
Color background = tableCellRendererComponent.getBackground();
cellComponent.setBackground(background);
}
我认为解释你做错了什么的最好方法是举个例子。假设在左列中右边的值高于左边的值,所以你的 if
发生并且 renderer
的背景变成 green
。现在,让我们渲染第 2 行。右边的值小于左边的值,因此 if
不会发生。你猜怎么着?您在前一行渲染中将其设为绿色,因此它保持 green
。这就是为什么他们一直保持绿色。如果你把它转一次,你不恢复它,它会留给其他人。
现在,您正在尝试恢复背景super.getTableCellRendererComponent(table, valueAt, isSelected, hasFocus, row, column - 1);
。这是错误的,因为这个方法不是简单的 getter。它还对 table(渲染器)进行了更改。为另一个 row/column 值调用此方法将不起作用。
为了使其正常工作,您必须根据来自 DefaultTableCellRenderer
的默认值恢复它。一个完整的例子:
public class Example extends JFrame {
private static final long serialVersionUID = 811854316682851407L;
private static final String[] COLUMNS = { "Current Chapter", "Chapter Online" };
public Example() {
super("test");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JTable table = new JTable(data(), COLUMNS);
table.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (c instanceof JLabel) {
JLabel renderer = (JLabel) c;
int valueAt = (int) table.getValueAt(row, column);
int compareValue = (int) table.getValueAt(row, column - 1);
if (compareValue < valueAt) {
renderer.setBackground(Color.GREEN);
} else {
if (isSelected)
renderer.setBackground(table.getSelectionBackground());
else {
renderer.setBackground(table.getBackground());
}
}
}
return c;
}
});
JScrollPane sp = new JScrollPane(table);
add(sp);
pack();
setLocationRelativeTo(null);
}
private Object[][] data() {
Object[][] data = { { 113, 444 }, { 233, 555 }, { 110, 92 }, { 55, 66 }, { 123, 603 }, { 412, 120 }, };
return data;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Example().setVisible(true));
}
}
预览: