当前位置: 首页 > 知识库问答 >
问题:

在运行时设置JTable行的颜色

邵修诚
2023-03-14

我的Java 8小程序连接到一个SQL数据库,并在一个JTable中显示“SELECT”语句的结果,该语句包含两列:

如果第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来代替我在开始时设置的DefaulTableModel但是我该如何使用它呢?我发现的所有东西都用固定支票。

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

(例如这里或这里),但在我的例子中,我不知道创建表时的任何内容,因为它是填充的/行是在运行时添加的。

我也找到了这个答案,但是问题的作者读取数据,然后更改模型,然后才填充表,而我逐行填充表(直接在读取行的内容之后)。

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

编辑:

下面是一些用于填充表格的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"
    }
));

结果:

所需结果(每一个新的“Column A”值为灰色背景):

备选结果(备选标记组的所有行):

共有1个答案

阎坚成
2023-03-14
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;
    }
});

由于renderer/renderer组件被重用用于所有表格单元格,因此必须为所有情况设置背景。

通常,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));
 类似资料:
  • 问题内容: 使用IKVM时,如何在运行时设置CLASSPATH变量? 我一直在尝试使用以下方法: 我正在调用的类需要在类路径中使用配置文件才能工作-而且我不断收到错误消息,似乎表明它没有获得设置。 我尝试添加变量的方式不正确吗? 问题答案: 我试图做同样的事情。我将一些jar文件编译为.Net dll,但是其中一些(第3方)jar文件正试图从java类路径中加载其配置文件。 我通过为ikvmc工具

  • 上游集群支持以下运行时配置: 主动健康检查 health_check.min_interval 健康检查间隔的最小值。默认值为0。运行状况检查间隔将介于min_interval和max_interval之间。 health_check.max_interval 健康检查间隔的最大值。默认值是MAX_INT。健康检查间隔将在min_interval和max_interval之间。 health_ch

  • HTTP连接管理器支持以下运行时设置: tracing.client_enabled 如果设置了x-client-trace-id头部,请求将被强制跟踪的百分比。默认为100。 tracing.global_enabled 在所有其他检查(强制跟踪,采样等)生效之后,将被跟踪的请求百分比。默认为100。 tracing.random_sampling 被随机跟踪的请求万分比。浏览此处获取更多信息。

  • 我不熟悉JTable。 我想在button press事件中在运行时更新jtable数据。 这是我的密码。 但按下“更新”按钮后不会更新。 有人能解决我的问题吗? 提前谢谢。。

  • 问题内容: 在已经加载(运行)JVM之后,是否可以更改/修改/添加VM参数?如果是这样,我该怎么办? 问题答案: 对于通过命令行上的标志设置的属性,您需要System.setProperty。例如: 更新: 您无法动态启用调试,但是可以在启动时启用调试,但稍后再附加调试器。通过以下操作,您可以侦听端口12345并立即开始运行程序(通过)。然后,您可以在需要时附加调试器,分离调试器,稍后再附加等。

  • 问题内容: 使用jQuery在运行时设置标签属性的最佳方法是什么? 另外,如何使用jQuery 获取标签属性的值? 问题答案: 要获取或设置HTML元素的属性,可以在jQuery中使用该函数。 要获取 href 属性,请使用以下代码: 要设置 href 属性,请使用以下代码: 在这两种情况下,请使用适当的选择器。如果已为anchor元素设置了类,请使用;如果已为anchor元素设置了id,请使用。