2012-10-05 51 views
0

使用jTableDefaultTableModel時出現問題。jTable,覆蓋DefaultCellRenderer不會在排序後重新繪製圖標

我有兩列顯示圖標使用覆蓋DefaultTableCellRenderer

private static ImageIcon errorIcon = new ImageIcon("workDir/icons/error.png"); 
private static ImageIcon pageIcon = new ImageIcon("workDir/icons/page_white.png"); 
private static ImageIcon serverIcon = new ImageIcon("workDir/icons/server_go.png"); 
private static ImageIcon acceptIcon = new ImageIcon("workDir/icons/accept.png"); 

private class ImageRenderer extends DefaultTableCellRenderer { 

    JLabel lbl = new JLabel(); 

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

     //lbl.setText((String) value); 
     lbl.setVerticalAlignment(SwingConstants.CENTER); 
     lbl.setHorizontalAlignment(SwingConstants.CENTER); 

     if (value.equals("e")) { 
      lbl.setIcon(pageIcon); 
      return lbl; 
     } 

     ServiceTicket t = TICKET_DICT.get((UUID) tableModel.getValueAt(row, 3)); 

     if (t == null) { 
      throw new IllegalStateException("Cannot find Ticket for UUID"); 
     } 

     if (t.getReport().getElsterCode().equals("0")) { 
      if (t.getSendMode().equals(EricSendMode.VALIDATE_LOCALLY)) { 
       lbl.setIcon(acceptIcon); 
      } else { 
       lbl.setIcon(serverIcon); 
      } 
     } else { 
      lbl.setIcon(errorIcon); 
     } 

     lbl.repaint(); 
     return lbl; 
    } 
} 

我在視圖的初始化階段設置ImageRenderer

resultTable.getColumnModel().getColumn(0).setCellRenderer(new ImageRenderer()); 
    resultTable.getColumnModel().getColumn(4).setCellRenderer(new ImageRenderer()); 

我希望我的表是排序。所以我用這個行來啓用默認排序:

resultTable.setAutoCreateRowSorter(true); 

我的問題是,現在整理效果很好,但在列0的圖標和4 sort事件後,不會重新繪製。

我嘗試添加一個事件告訴單元格值已經更改了表,但沒有奏效:

resultTable.getRowSorter().addRowSorterListener(
      new RowSorterListener() { 

       @Override 
       public void sorterChanged(RowSorterEvent e) {       
        if (e.getType().equals(RowSorterEvent.Type.SORTED)) { 
         for (int i = 0; i < tableModel.getRowCount(); i++) { 
          tableModel.fireTableCellUpdated(i, 0); 
          tableModel.fireTableCellUpdated(i, 4); 
         } 
        } 

       } 
      }); 

你能不能幫我把表進行排序後重新繪製的圖標。我檢查了表模型,並且所有單元格和列都被正確排序。即使是渲染爲圖標的單元格中的值。

謝謝!

+1

*從來沒有*甚至想到代表模型發射事件:一個行爲良好的實現必須適當地觸發它們。更糟糕的是:在排序器Listener中這樣做可能會產生無盡的循環... – kleopatra

+0

是的,你是對的,謝謝!我在另一種方法中產生了StackOverFlowExceptions! –

回答

2

一些評論其實不是一個答案,但太長的評論。

ServiceTicket t = TICKET_DICT.get((UUID) tableModel.getValueAt(row, 3)); 

將在對錶進行排序時從TableModel中檢索不正確的值。此時,傳遞的row索引與模型中的索引row上的元素(由於排序)不匹配。使用JTable#convertRowIndexToModel將索引轉換爲模型索引。

另外,當分揀機改變時調用fireTableCellUpdated的收聽者不需要,甚至不正確。雖然表格可能會更改元素的顯示順序,但底層數據沒有任何變化。

而在去年

我檢查表模型,所有單元格和列得到正確排序。即使是單元格中的值呈現爲圖標

不確定「檢查表模​​型」的含義。排序時,沒有任何更改爲TableModel。排序只發生在視圖方面,而不是模型方面。

+0

_event排序後的代碼不是必需的_ehhh ...它是完全錯誤的(因爲_you_知道:-) – kleopatra

+1

@kleopatra我重新說了這句話。希望現在更清楚 – Robin

+0

謝謝!這解決了它! –