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

时间:2011-04-30 09:49:38

标签: swing background jtable

每个人,

我试图在迭代后在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.");
     }
 }

有关于此的任何提示吗?

1 个答案:

答案 0 :(得分:4)

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

  
      
  • 永远不要在渲染器上进行任何直接操作/绘制,而是更改模型数据,其余的将自动发生。
  •   
  • 从不在模型外部调用模型上的任何fireXX方法,模型的唯一责任是通知   它的听众正在改变
  •   
  • 从来没有(或者非常非常,当然不在这里;-)需要调用revalidate和/或重新调用dircectly,将会发生   如果模型表现良好,则自动
  •   
  • ....
  •   

最好阅读Snoracle关于如何使用表格来完全理解渲染机制的教程

http://download.oracle.com/javase/tutorial/uiswing/components/table.html

大致是:

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