Swing JTable-无法重新绘制和更改单元格的背景

Swing JTable-无法重新绘制和更改单元格的背景,swing,background,jtable,Swing,Background,Jtable,为什么大家, 我试图在迭代后在JTable中进行一些计算,并用不同的背景标记我需要的单元格 然而,目前我有两个问题: 1) 单元格不会立即绘制,而是在整个迭代周期之后绘制 2) 区域未正确绘制-如果我需要绘制表[3,4]和表[6,5],它将绘制一个从[3,4]到[6,5]的矩形,而不是仅绘制单个单元格 关于问题1:我是否可以使用优先级调用repaint(),而不需要完成所有工作,也不需要JVM决定何时进行绘制?我尝试执行fireTableCellUpdated()和fireTableDataCh

为什么大家,

我试图在迭代后在JTable中进行一些计算,并用不同的背景标记我需要的单元格

然而,目前我有两个问题:
1) 单元格不会立即绘制,而是在整个迭代周期之后绘制
2) 区域未正确绘制-如果我需要绘制表[3,4]和表[6,5],它将绘制一个从[3,4]到[6,5]的矩形,而不是仅绘制单个单元格

关于问题1:我是否可以使用优先级调用repaint(),而不需要完成所有工作,也不需要JVM决定何时进行绘制?我尝试执行
fireTableCellUpdated()
fireTableDataChanged()
但它们没有得到更新

这里是我的自定义单元格渲染器方法,可更改BGcolor:

public Component getTableCellRendererComponent(JTable table, Object value,
    boolean isSelected, boolean hasFocus, int row,int column) {
    Component renderer = super.getTableCellRendererComponent(
        table, value, isSelected, hasFocus, row, column);

    if(value instanceof Color) {
        Color c = (Color) value;
        renderer.setBackground(c);
        System.out.println("BG change [" + row + ":" + column + "]");
    }

    return renderer;
}
这里有一个循环,我在单击按钮时绘制单元格:

for(int paintJ = startIndex; paintJ < endIndex; paintJ++) {
     CrossCellRenderer rend =  (CrossCellRenderer) jTable1.getCellRenderer(i,  paintJ)
           .getTableCellRendererComponent(jTable1, Color.blue, true, true, i, paintJ);
     crossTableModel.fireTableCellUpdated(i, paintJ);
     jTable1.revalidate();
     jTable1.repaint();
     try {
          Thread.sleep(1000);
     }   catch(InterruptedException ie) {
           System.err.println("Exception sleeping the thread.");
     }
 }
for(int-paintJ=startIndex;paintJ

有什么建议吗?

我不想说:但是你做的(无论你想做什么)完全错了;-)

  • 永远不要在渲染器上进行任何直接操作/绘制,而是更改模型数据,其余操作将自动进行
  • 永远不要从模型外部调用模型上的任何fireXX方法,通知是模型的专属责任 它的听众在改变
  • 永远不会(或者很少,这里肯定不会;-)需要直接调用重新验证和/或重新绘制 如果模型表现良好,则自动执行
最好阅读Snoracle的教程,了解如何使用表来充分理解渲染机制

大致:

   // change the model, will notify its listeners
   model.setValueAt(....)

   // in a custom renderer, check the value and decorate as appropriate
   public Component getTableCellRendererComponent(....) {
        // ... normal config, f.i. done in super
        Component comp = super.get...
        if (myConditionForSpecialColor(table, value, ...) {
            comp.setBackground(myColor);
        } else {
            comp.setBackground(normalColor);
        }
   }

   // register the custom renderer 
   // per class
   table.setDefaultRenderer(Object.class, myRenderer)
   // or per column
   table.getColumnModel().getColumn(myColumn).setCellRenderer(myRenderer) 

讨厌说:但是你做的(无论你想做什么)完全错了;-)

  • 永远不要在渲染器上进行任何直接操作/绘制,而是更改模型数据,其余操作将自动进行
  • 永远不要从模型外部调用模型上的任何fireXX方法,通知是模型的专属责任 它的听众在改变
  • 永远不会(或者很少,这里肯定不会;-)需要直接调用重新验证和/或重新绘制 如果模型表现良好,则自动执行
最好阅读Snoracle的教程,了解如何使用表来充分理解渲染机制

大致:

   // change the model, will notify its listeners
   model.setValueAt(....)

   // in a custom renderer, check the value and decorate as appropriate
   public Component getTableCellRendererComponent(....) {
        // ... normal config, f.i. done in super
        Component comp = super.get...
        if (myConditionForSpecialColor(table, value, ...) {
            comp.setBackground(myColor);
        } else {
            comp.setBackground(normalColor);
        }
   }

   // register the custom renderer 
   // per class
   table.setDefaultRenderer(Object.class, myRenderer)
   // or per column
   table.getColumnModel().getColumn(myColumn).setCellRenderer(myRenderer) 

请尝试修复格式(代码标记不起作用/此处不需要):缩进4个字符足够请尝试修复格式(代码标记不起作用/此处不需要):缩进4个字符足够您好,kleopatra,感谢您的批评意见-这非常有帮助。我绝对同意你的最佳做法。然而,我尝试了模型内外的模型操作,包括在演示中使用jTable以及渲染器。我只是试着从不同的动作中调用事件。然而,你的观点在上下文之外是绝对正确的,我真的很感激。正在测试你的演示。我根据你上面的建议对我的代码做了一些修改。然而,情况是这样的——表数据是静态的,我需要触发一个JButton,它迭代我的表并在必要时着色。“我的渲染器”已注册为表的默认值,但没有更新。再次感谢您的帮助。@Mario有一些事情需要改变(否则您就不想重新上色)。将“某物”与静态日期一起封装在TableModel中,如果“某物”发生更改,则让模型启动我的错误是设置了渲染器颜色一次,但缺少normalColor部分。现在渲染器工作正常。另外,为了能够一个字母一个字母地画,我开始画线。谢谢你的建议。你好,克利奥帕特拉,谢谢你的批评意见-这很有帮助。我绝对同意你的最佳做法。然而,我尝试了模型内外的模型操作,包括在演示中使用jTable以及渲染器。我只是试着从不同的动作中调用事件。然而,你的观点在上下文之外是绝对正确的,我真的很感激。正在测试你的演示。我根据你上面的建议对我的代码做了一些修改。然而,情况是这样的——表数据是静态的,我需要触发一个JButton,它迭代我的表并在必要时着色。“我的渲染器”已注册为表的默认值,但没有更新。再次感谢您的帮助。@Mario有一些事情需要改变(否则您就不想重新上色)。将“某物”与静态日期一起封装在TableModel中,如果“某物”发生更改,则让模型启动我的错误是设置了渲染器颜色一次,但缺少normalColor部分。现在渲染器工作正常。另外,为了能够一个字母一个字母地画,我开始画线。谢谢你的提示。