为啥我的 JTable CellRenderer 一直在运行?

Posted

技术标签:

【中文标题】为啥我的 JTable CellRenderer 一直在运行?【英文标题】:Why is my JTable CellRenderer running all the time?为什么我的 JTable CellRenderer 一直在运行? 【发布时间】:2011-05-31 03:31:00 【问题描述】:

//新手问题

我有一个带有几乎基本单元格渲染器的 JTable(它为线条着色不同)。 我注意到我的单元格渲染器一直在为屏幕上显示的线条运行,即使我没有对表格做任何事情。

这是应该的吗?它不应该将每个单元格渲染一次,就是这样吗? 我怎样才能让它停止,并且只重新计算变化?

public Component getTableCellRendererComponent(JTable table, Object value,
    boolean isSelected, boolean hasFocus, int row, int column) 

   log.debug("Building cell : " + row + "," + column);

   Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

   Filter filter = (Filter)table.getModel().getValueAt(row, Column.CLASSIFICATION.getIndex());
   comp.setBackground(filter.getColor());
   return comp;

  

【问题讨论】:

这是不正确的行为。你能创建一个独立的代码示例来演示这一点吗?它将帮助我们解决此问题。 @Steve 我认为这将是太多的代码。我刚刚发现我有另一个渲染器,用于表格中的特定单元格。难道是他们互相开火? 它可以是任何东西。心理调试很难。只是一个创建 JFrame、添加表格、设置单元格渲染器的主要方法,就像您已经展示的那样 - 并且有同样的问题。 请注意,当你的表被排序时,你会从你的模型中检索到错误的Filter。作为参数传递的row 在“表视图坐标”中,而不是在“模型坐标”中 【参考方案1】:

根据@Steve McLeod 的提议,我开始构建具有相同错误的示例代码,然后我才意识到在我的一个 CellRenderer 中

@Override
    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) 

        log.debug("Building a list for " + row + "," + column);
        setListData(((Vector<String>)value).toArray());     
        setToolTipText("This is a tool tip for " + row + "," + column);

        table.setRowHeight(row, Math.max(1, getPreferredSize().height));
        Filter filter = (Filter)table.getModel().getValueAt(row, Column.CLASSIFICATION_RESULT.getIndex());
        setBackground(filter.getColor());       
        return this;
    

我有电话:

table.setRowHeight(row, Math.max(1, getPreferredSize().height));

它不断地改变行 line ,而同一行中的其他渲染器也做了同样的事情...... 所以他们不断地互相射击。

【讨论】:

【参考方案2】:

我已经使用包含 很多 数据的 JTables 工作了 很多。超过 99.9% 的 Java 程序员通常操作的。您需要知道一件事:默认情况下,会产生大量浪费,并完成大量通常不必要的操作。

如果您追求快速高效的 JTable,那么 Sun 的权威文章就是关于这个主题的:

“圣诞树应用,如何创建经常更新且性能良好的 JTable”

注意标题中的“表现良好”,因为默认情况下,JTable 性能非常非常糟糕:

Original Link (Sun)

Current link (Oracle)

Archived Version:

在实施该文章中建议的两三个技术后,您会注意到 JTable 渲染的惊人加速,并且您会注意到生成的垃圾更少(因此 GC 需要更少地启动) .

【讨论】:

为圣诞树页面添加了存档链接,因为原始链接已失效。它会在我的编辑审核后显示。 JTable 性能真的非常糟糕 如果这是真的,那么按照文章中的糟糕(用于生产代码)绘制捷径想法不会有太大变化: 它甚至没有提高一个数量级 ;-)【参考方案3】:

我注意到您根据另一个单元格的值更改了一个单元格的外观。如果这种关系是双向的 - 单元格 1 的外观基于单元格 2,反之亦然,您可能会遇到这样的问题。但实际上,我们需要一个能够重现问题的独立代码示例 - 否则我们只能在黑暗中拍摄。

【讨论】:

【参考方案4】:

渲染器已经缓存了你渲染的组件,当没有任何变化时,什么都不会重新渲染

但是,当表格检测到某些内容可能已更改时,它将请求重新渲染。 触发它最多的事件是鼠标移动。

所以是的,它对于 JTable 的正常行为。

【讨论】:

我是这么想的,但事实并非如此:当桌子在屏幕上,而鼠标没有移动时,我仍然看到我的日志消息像疯了一样运行 这是“正常的”,因为默认的 JTable 实现非常糟糕。我链接的文章也解释了如何为经常更新的 JTables 获得正常和快速的行为。 当用户没有用鼠标或表格做任何事情时,不断调用渲染器是不正常的。您的程序中有一些代码必须循环或其他东西。发布您的 SSCCE (sscce.org) 来证明问题。

以上是关于为啥我的 JTable CellRenderer 一直在运行?的主要内容,如果未能解决你的问题,请参考以下文章

JTable:单击按钮时更改单元格背景

如何为 JTable 中的单元格着色? [复制]

为啥在gtkmm中使用CellRenderer时TreeView中会显示两次信息

java中JTable表格实现添加图片的渲染

如何将JComboBox添加到JTable单元格?

如何使用自定义 JTable 单元格编辑器和单元格渲染器