在运行时设置JTable行的颜色 [英] Set color of JTable row at runtime

查看:65
本文介绍了在运行时设置JTable行的颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Java 8小程序连接到SQL数据库,并在JTable的两列中显示"select"语句的结果:

My Java 8 applet connects to an SQL database and displays the result of a "select" statement in a JTable with two columns:

如果第1行/ColumnA中的字符串与第0行/ColumnA中的字符串不同,我想给第1行提供灰色背景色(以标记新"数据的开始),其他行应该使用默认的白色.

If the String in row 1/ColumnA isn't the same as the String in row 0/ColumnA, I want to give row 1 a grey background color (to mark the start of "new" data), the other rows should use the default white color.

用于创建表的代码:

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,但是如何使用它呢?我发现的所有内容都使用固定检查,例如

From what I've found so far, I have to use a custom TableModel instead of the DefaultTableModel I set in the beginning but how do I use it? Everything I've found uses fixed checks, e.g.

如果单元格中的内容为购买",则将背景色设置为绿色"

if content in the cell is 'buy', set the background color to 'green'

(例如此处

(e.g. here or here) but in my case I don't know anything about the content when the table is created because it's filled/rows are added at runtime.

我还找到了答案,但是问题的作者读取了数据,然后更改了模型,然后才填充表格时,我逐行填写表格(在读取行的内容之后立即).

I also found this answer but the author of the question reads the data, then changes the model and only then fills the table, while I fill the table row by row (directly after reading the row's content).

我的问题:我知道如何将单元格的内容与上一行中的单元格的内容进行比较,但是如何在运行时设置行的背景色?

My question: I know how to compare the content of a cell to content of the cell in the previous row but how do I set the background color of the row at runtime?

这是一些用于填写表格的MRE代码.请注意:如果您对如何完成自己的工作提出建议,请记住我正在使用数据库和ResultSet(请参见上面的代码),而不是预定义的数据(请参见下面的代码) !

Here's some MRE code for filling the table. Please note: If you post a suggestion about how to accomplish what I want to do, keep in mind that I'm working with a database and a ResultSet (see code above), not pre-defined data (see code below)!

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列"值的背景为灰色):

Desired result (grey background for every new "Column A" value):

替代结果(替代标记组的所有行):

Alternative result (alternate marking all rows of a group):

推荐答案

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;
    }
});

由于渲染器/渲染器组件已在所有表格单元中重复使用,因此必须为所有情况设置背景.

As the renderer / renderer component is reused for all table cells, the background must be set for all cases.

通常,JTable的TabelModel优于JTable的getValueAt来获取值,但是显然您既不对行进行排序也不对列进行重新排列.

In general the JTable's TabelModel is better for getting a value instead of JTable's getValueAt, but evidently you neither sort the rows nor rearrange the columns.

对于可能安装的较旧渲染器

For a possible older installed renderer

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));

这篇关于在运行时设置JTable行的颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆