Domanda

Ho un JTable con 3 colonne. Ho impostato il TableCellRenderer per tutti i 3 colonne come questo (forse non molto efficace?).

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

Il getTableCellRendererComponent() restituisce un componente con un colore di sfondo casuale per ogni riga.
Come potrei cambiare lo sfondo ad un altro colore casuale mentre il programma è in esecuzione?

È stato utile?

Soluzione

Un modo potrebbe essere memorizzare il colore corrente per ogni riga all'interno del modello. Ecco un semplice modello che viene fissato a 3 colonne e 3 righe:

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

Si noti che setRowColour chiama fireTableRowsUpdated; questo causerà solo tale riga della tabella da aggiornare.

Il renderer può ottenere il modello dalla tabella:

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

Cambiare il colore di una fila sarebbe semplice come:

model.setRowColour(1, Color.YELLOW);

Altri suggerimenti

Resumee della risposta di Richard Fearn, per rendere ogni secondo di Gray Line:

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

Le altre risposte qui riportati funzionano bene da quando si utilizza lo stesso renderer in ogni colonna.

Tuttavia, tendo a credere che in genere quando si utilizza un JTable si avrà diversi tipi di dati in ogni columm e, pertanto, non sarà utilizzando lo stesso renderer per ogni colonna. In questi casi si può trovare la Table Row rendering approccio utile .

Questo è fondamentalmente semplice come ridipingere la tavola. Non ho trovato un modo per ridisegno selettivamente solo una riga / colonna / cella tuttavia.

In questo esempio, facendo clic sul pulsante cambia il colore di sfondo per una riga e quindi chiama riverniciare.

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

La chiamata alla getTableCellRendererComponent(...) include il valore della cella di cui si chiede un renderer.

È possibile utilizzare questo valore per calcolare un colore. Se si sta utilizzando anche un AbstractTableModel, è possibile fornire un valore di tipo arbitrario renderer.

Una volta che hai un colore, è possibile setBackground() sul componente che si sta tornando.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top