2010-10-06 9 views
18

Ich habe eine JTable mit 3 Spalten. Ich habe die TableCellRenderer für alle 3 Spalten so eingestellt (vielleicht nicht sehr effektiv?).Ändern Sie die Hintergrundfarbe einer Zeile in einer JTable

for (int i = 0; i < 3; i++) { 
    myJTable.getColumnModel().getColumn(i).setCellRenderer(renderer); 
} 

Die getTableCellRendererComponent() kehrt eine Komponente mit einer zufälligen Hintergrundfarbe für jede Zeile.
Wie kann ich den Hintergrund in eine andere zufällige Farbe ändern, während das Programm läuft?

Antwort

20

Eine Möglichkeit wäre, die aktuelle Farbe für jede Zeile innerhalb des Modells zu speichern. Hier ist ein einfaches Modell, das auf drei Säulen und drei Reihen befestigt ist:

static class MyTableModel extends DefaultTableModel { 

    List<Color> rowColours = Arrays.asList(
     Color.RED, 
     Color.GREEN, 
     Color.CYAN 
    ); 

    public void setRowColour(int row, Color c) { 
     rowColours.set(row, c); 
     fireTableRowsUpdated(row, row); 
    } 

    public Color getRowColour(int row) { 
     return rowColours.get(row); 
    } 

    @Override 
    public int getRowCount() { 
     return 3; 
    } 

    @Override 
    public int getColumnCount() { 
     return 3; 
    } 

    @Override 
    public Object getValueAt(int row, int column) { 
     return String.format("%d %d", row, column); 
    } 
} 

Beachten Sie, dass setRowColour ruft fireTableRowsUpdated; Dadurch wird nur diese Zeile der Tabelle aktualisiert.

Der Renderer kann das Modell aus der Tabelle erhalten:

static class MyTableCellRenderer extends DefaultTableCellRenderer { 

    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
     MyTableModel model = (MyTableModel) table.getModel(); 
     Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 
     c.setBackground(model.getRowColour(row)); 
     return c; 
    } 
} 

eine Zeile der Farbe ändern wäre so einfach wie:

model.setRowColour(1, Color.YELLOW); 
1

Dies ist im Grunde so einfach wie die Tabelle neu zu streichen. Ich habe jedoch keine Möglichkeit gefunden, nur eine Zeile/Spalte/Zelle selektiv neu zu zeichnen.

In diesem Beispiel ändert das Klicken auf die Schaltfläche die Hintergrundfarbe für eine Zeile und ruft dann Repaint auf.

public class TableTest { 
    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     final Color[] rowColors = new Color[] { 
       randomColor(), randomColor(), randomColor() 
     }; 
     final JTable table = new JTable(3, 3); 
     table.setDefaultRenderer(Object.class, new TableCellRenderer() { 
      @Override 
      public Component getTableCellRendererComponent(JTable table, 
        Object value, boolean isSelected, boolean hasFocus, 
        int row, int column) { 
       JPanel pane = new JPanel(); 
       pane.setBackground(rowColors[row]); 
       return pane; 
      } 
     }); 
     frame.setLayout(new BorderLayout()); 

     JButton btn = new JButton("Change row2's color"); 
     btn.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       rowColors[1] = randomColor(); 
       table.repaint(); 
      } 
     }); 

     frame.add(table, BorderLayout.NORTH); 
     frame.add(btn, BorderLayout.SOUTH); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    private static Color randomColor() { 
     Random rnd = new Random(); 
     return new Color(rnd.nextInt(256), 
       rnd.nextInt(256), rnd.nextInt(256)); 
    } 
} 
1

Der Aufruf von getTableCellRendererComponent(...) den Wert der Zelle enthält, für die ein Renderer wird gesucht.

Sie können diesen Wert verwenden, um eine Farbe zu berechnen. Wenn Sie auch ein AbstractTableModel verwenden, können Sie Ihrem Renderer einen beliebigen Wert zuweisen.

Sobald Sie eine Farbe haben, können Sie setBackground() auf der Komponente, die Sie zurückgeben.

15

Die anderen hier angegebenen Antworten funktionieren gut, da Sie in jeder Spalte denselben Renderer verwenden.

Ich neige jedoch zu der Annahme, dass bei Verwendung einer JTable normalerweise unterschiedliche Datentypen in jeder Spalte vorhanden sind und daher nicht für jede Spalte derselbe Renderer verwendet wird. In diesen Fällen können Sie den Table Row Rendering Ansatz hilfreich finden.

+0

Ich bin damit einverstanden. Es scheint mir, dass 'TableModel' Tabellendaten enthalten soll. Rendering sollte woanders durchgeführt werden. Der verlinkte Artikel ist aufschlussreich, danke! :) – Matthieu

+0

Dies sollte als Antwort markiert werden. –

20

Resumee von Richard Fearn Antwort, jede zweite Zeile grau zu machen:

jTable.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() 
{ 
    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) 
    { 
     final Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 
     c.setBackground(row % 2 == 0 ? Color.LIGHT_GRAY : Color.WHITE); 
     return c; 
    } 
}); 
+0

Sie haben Recht, das funktioniert, aber warum funktioniert das nur für die ersten 5 Spalten? irgendeine Idee? – Sahan

+0

@Sahan, da hinter der 5. Spalte möglicherweise ein benutzerdefinierter Cell-Renderer vorhanden ist. – Enkuushka

+0

Ich habe diesen Olivier ausprobiert, aber nachdem ich diesen Code über dem Effekt benutzt habe, kann ich nicht .setSelectionBackground (Color.yellow); länger.... :( – gumuruh