web-dev-qa-db-fra.com

Modifier la couleur d'arrière-plan d'une ligne dans une table JTable

J'ai un JTable avec 3 colonnes. J'ai défini le TableCellRenderer pour les 3 colonnes comme celle-ci (peut-être pas très efficace?).

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

La getTableCellRendererComponent() renvoie un composant avec une couleur d'arrière-plan aléatoire pour chaque ligne.
Comment pourrais-je changer l'arrière-plan en une autre couleur aléatoire pendant l'exécution du programme?

20
user

Une façon serait de stocker la couleur actuelle de chaque ligne du modèle. Voici un modèle simple qui est fixé à 3 colonnes et 3 lignes:

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);
    }
}

Notez que setRowColour appelle fireTableRowsUpdated; cela entraînera la mise à jour de cette seule ligne du tableau.

Le moteur de rendu peut obtenir le modèle à partir du tableau:

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;
    }
}

Changer la couleur d'une ligne serait aussi simple que:

model.setRowColour(1, Color.YELLOW);
21
Richard Fearn

Résumé de la réponse de Richard Fearns, pour rendre chaque deuxième ligne grise:

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;
    }
});
24
Olivier Faucheux

Les autres réponses données ici fonctionnent bien car vous utilisez le même rendu dans chaque colonne.

Cependant, j'ai tendance à croire qu'en général, lorsque vous utilisez un JTable, vous aurez différents types de données dans chaque colonne et donc vous n'utiliserez pas le même rendu pour chaque colonne. Dans ces cas, vous pouvez trouver l'approche Tableau Row Rendering utile.

15
camickr

L'appel à getTableCellRendererComponent(...) inclut la valeur de la cellule pour laquelle un rendu est recherché.

Vous pouvez utiliser cette valeur pour calculer une couleur. Si vous utilisez également un AbstractTableModel, vous pouvez fournir une valeur de type arbitraire à votre moteur de rendu.

Une fois que vous avez une couleur, vous pouvez setBackground() sur le composant que vous retournez.

1
Andy Thomas

C'est aussi simple que de repeindre la table. Je n'ai cependant pas trouvé de moyen de repeindre sélectivement une seule ligne/colonne/cellule.

Dans cet exemple, cliquer sur le bouton change la couleur d'arrière-plan d'une ligne, puis appelle repeindre.

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
Mark Peters