2013-05-06 16 views
2

我試圖能夠在JTable中對單元格進行顏色分離,但我只能在整列上應用TableCellRenderer,這顯然會導致功能故障。我有一個自定義的JTable:在單個單元格上應用TableCellRenderer

public class JColorTable extends JTable{ 
    (...) 
    public void setCellColor(int col, int row, Color newColor) { 
    getColumnModel().getColumn(col).setCellRenderer(new ColorField(col, row, newColor, background)); 
    repaint(); 
    } 
} 

ColorField看起來是這樣的:

class ColorField extends DefaultTableCellRenderer { 

    (...)) 

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

     JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 

     if (row == newRow && column == newCol) { 
      l.setBackground(Color.red); 
     } else { 
      l.setBackground(defaultColor); 
     } 

     return l; 
    } 
} 

這就像一個魅力時,我有一列的單一有色格,但是當我嘗試到彩色另一個單元格該列,前一個被刪除(由於ColorField中的條件不適用於前一列)。

有沒有辦法只將ColorField應用於單個單元而不是整列?如果是這樣,怎麼樣?恐怕我沒有找到合適的東西。

回答

3

JTable有一個方法getCellRenderer(),您可以覆蓋。它在單元需要渲染並根據行和列返回一個時調用。

您的JTable需要爲每個單元(按行和列)保留使用哪個渲染器的某些記錄。一個二維數組可以做到這一點,或者一個Map的關鍵是一個X,Y值。

添加一種方法來設置特定單元格上的渲染器(按行和列),然後您就可以使用了。

class MyTable extends JTable { 

    // all the other JTable stuff goes here too ... 

    public TableCellRenderer getCellRenderer(int row, int column) { 
     TableCellRenderer myRenderer = getCustomRenderer(row, column); 
     if (myRenderer != null) { 
      return myRenderer; 
     } 
     // else... 
     return super.getCellRenderer(row, column); 
    } 

    private Map<Integer, Map<Integer, TableCellRenderer>> rendererMap = new ...; 

    public void setCustomRenderer(int row, int column, TableCellRenderer renderer) { 
     Map<Integer, TableCellRenderer> m1 = rendererMap.get(row); 
     if (m1 == null) { 
      m1 = new ...; 
      rendererMap.put(row, m1); 
     } 
     m1.put(column, renderer); 
    } 

    public TableCellRenderer getCustomRenderer(int row, int column) { 
     Map<Integer, TableCellRenderer> m1 = rendererMap.get(row); 
     if (m1 == null) { 
      return null; 
     } 
     return m1.get(column); 
    } 
} 

getTableCellRenderer默認的版本使用的渲染器的列設置,如果有一個,如果不是它使用基於類的單元格內容的渲染器。在很多情況下,默認的單元格內容是Object。這取決於使用的TableModel

+1

的getCustomRenderer方法應該是類型的TableCellRenderer而不是空隙。 – 2013-09-30 22:46:17

+0

@JorgeBlancoSegura謝謝。修復。也許StackOverflow需要一個內置的Java IDE來確保我輸入的代碼很好。 :) – 2013-09-30 23:00:11

+0

請參閱此[清潔實施](http://stackoverflow.com/a/16408257/418556)。 – 2014-05-19 19:59:43

0

您需要某個列中每個單元格的顏色信息。該信息可以駐留在值:然後

class CellValue { 
    Color getBackgroundColor() { ... } 
    String getCellContent() { ... } 
} 

getTableCellRendererComponent()方法看起來是這樣的:

CellValue cellValue = (CellValue) value; 
Color bgColor = cellValue.getBackgroundColor(); 
String text = cellValue.getCellContent(); 

JLabel l = (JLabel) super.getTableCellRendererComponent(table, text, isSelected, hasFocus, row, column); 

l.setBackground(bgColor); 

... 

當然,你必須適應你的TableModel來存儲CellValue實例。

3

就個人而言,我會避免任何需要您擴展JTable的解決方案。主要原因是它使您的代碼更加便於攜帶,並將您的渲染器緊密結合到JTable的特定實現中。它可能適合您的需求,但是,我個人總是試圖看到更大的圖片/潛力/重用

請記住,單元格渲染器綁定到表列。這並不意味着可以按照單元格來爲單元格提供自定義渲染。你可以做什麼,但是提供渲染邏輯爲每個單元格基於渲染器內的一系列條件

我可能會放在一起的某種條件/格式引擎,您可以使用它將單元格值和座標傳遞給,然後根據發動機特定實施的需要作出決定。

class ColorField extends DefaultTableCellRenderer { 

    (...)) 

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

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

     // CellFormat is an object you create to hold the various aspects 
     // of the cell format 
     // You could also pass in the selected and focused flags if you 
     // needed them... 
     // getFormatEngine is a method you would write to provide 
     // to gain access to the format engine 
     CellFormat format = getFormatEngine().getFormatFor(value, row, column); 
     setBackground(format.getBackground()); 
     setForeground(format.getForeground()); 
     setFont(format.getFont()); 
     // Any other properties you may wish to effect... 

     return this; 
    } 
} 

FormatEngine將是如何最好地給定的單元格的格式作出決策的基礎。它應該能夠提供「默認」格式

這意味着您可以爲特定的單元格類型設計「默認」渲染器,但能夠根據需要提供自定義渲染,而不需要多個if陳述或擴展基本呈現

這也是有條件的格式化引擎,在那裏你可以應用一系列的條件,對一個給定值,並返回基於結果

+1

這看起來比接受的答案更清晰。 – 2014-05-19 19:59:04

+0

有人會善意解釋downvote? – MadProgrammer 2015-05-25 21:27:49

0

我認爲正確的合適的格式基地實現這一點的方式是通過ColorHighlighter。 這在the documentation中說。這是一個related issue in SO

注意:如果該表允許排序它是必不可少實現一個相應ComponentAdapter,以其dapter.convertRowIndexToModel

相關問題