refreshing background color for a row in jtable
Asked Answered
D

2

2

i am trying to set the color of row of a Swing Jtable. i use this class to extend Jtable as suggest on the net.

    public class ColorTable extends JTable {


    private static final long serialVersionUID = 1L;
    private Map rowColor = new HashMap();
    private Map columnColor = new HashMap();
    private Color cellColor;
    private Color defaultColor;

    public ColorTable( TableModel model ) {
        super( model );
    }

    public void setRowColor( int row, Color c) {
        rowColor.put( new Integer( row ), c );
    }

    public void setColumnColor( int column, Color c ) {
        columnColor.put( new Integer( column ), c );
    }

    public void setCellColor( Color c ) {
        cellColor = c;
    }

    public Class getColumnClass(int column) {
        return getValueAt(0, column).getClass();
    }

    public Component prepareRenderer( TableCellRenderer renderer, int row, int column ) {

        Component c = super.prepareRenderer( renderer, row, column );
        if ( defaultColor == null )
            defaultColor = c.getBackground();

        // Color order is as follows:
        // rowSelection, checkBox toggle for row color, column color, cell color
        if ( ! isRowSelected( row ) ) {
            Color color = (Color) rowColor.get( new Integer( row ) );
            if ( color == null || Boolean.FALSE.equals( getModel().getValueAt( row, 0 ) ) )
                color = (Color) columnColor.get( new Integer( column ) );
            if ( color == null ) {
                // cell color only if cell has special value, for example purposes,
                // if the cell value begins with a 2
                Object value = getValueAt( row, column );
                if ( value != null && value.toString().startsWith( "2" ) )
                    color = cellColor;
            }
            if ( color != null )
                c.setBackground( color );
            else
                c.setBackground( defaultColor );
        }
        return c;
    }

    public void resetColor(Color color) {
        for(int i=0;i<this.getRowCount();i++)
            this.setRowColor(i, color);
    }
}

I simply added the method resetColor(Color color) in order to initialize all the row with the same color.

It seams to work at first use but when i want to change the colors i get problems. for instance if I execute the sollowing code within a button action listener i color the table properly just at the first iteration and after never changes the background.

deployTable.resetColor(Color.green);
// set red background to the
for (Integer x : indexes) { 
    System.out.println("index "+x+" red!");
    deployTable.setRowColor(x, Color.red);
}
deployTable.revalidate();

does anyone has any idea about what could it be??

Thanks, Ste

Dedededen answered 1/8, 2011 at 15:20 Comment(1)
I don't see repaint().Tripletail
S
8

for example,

enter image description here enter image description here

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import java.util.Vector;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;

public class Forum implements ListSelectionListener {

    private JFrame frame = new JFrame("Frame");
    private JPanel fatherCenter = new JPanel();
    private JScrollPane tableScroll = new JScrollPane();
    private myTableModel tableModel;
    private JTable dialogTable;
    private JButton blueButton;
    private ListSelectionModel lsDialog;
    private Color clr;
    private Color clr1;

    private void addComponentsToPane(Container pane) {
        tableModel = new myTableModel();
        dialogTable = new JTable(tableModel) {

            private static final long serialVersionUID = 1L;

            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                Component comp = super.prepareRenderer(renderer, row, column);
                JComponent jc = (JComponent) comp;//for Custom JComponent
                if (!isRowSelected(row)) {
                    int modelRow = convertRowIndexToModel(row);
                    boolean type = (Boolean) getModel().getValueAt(modelRow, 2);
                    boolean type1 = (Boolean) getModel().getValueAt(modelRow, 3);
                    comp.setForeground(Color.black);
                    if ((type) && (!type1)) {
                        comp.setBackground(clr1);
                    } else if ((!type) && (type1)) {
                        comp.setBackground(Color.orange);
                    } else if ((!type) || (!type1)) {
                        comp.setBackground(Color.red);
                    } else {
                        comp.setBackground(row % 2 == 0 ? getBackground() : getBackground().darker());
                    }
                    dialogTable.convertRowIndexToView(0);
                } else {
                    comp.setForeground(Color.blue);
                }
                if (!isCellEditable(row, column)) {
                    comp.setForeground(Color.red);
                    comp.setBackground(Color.magenta);
                }
                return comp;
            }
        };
        tableScroll = new JScrollPane(dialogTable, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        tableScroll.setBorder(null);
        dialogTable.getTableHeader().setReorderingAllowed(false);
        dialogTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        lsDialog = dialogTable.getSelectionModel();
        dialogTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
        dialogTable.setRowHeight(20);
        dialogTable.setRowMargin(2);
        ListSelectionModel rowSelMod = dialogTable.getSelectionModel();
        //ListSelectionModel colSelMod = dialogTable.getColumnModel().getSelectionModel();
        rowSelMod.addListSelectionListener(this);
        //colSelMod.addListSelectionListener(this);
        blueButton = new JButton(" Blue BackGround ");
        blueButton.setPreferredSize(new Dimension(100, 30));
        blueButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                if (clr == Color.white) {
                    clr = Color.orange;
                    clr1 = Color.yellow;
                } else {
                    clr = Color.white;
                    clr1 = Color.black;
                }
                System.out.println(clr);
                dialogTable.setBackground(clr);
                dialogTable.repaint();
            }
        });
        fatherCenter = new JPanel();
        fatherCenter.setLayout(new BorderLayout(10, 10));
        fatherCenter.add(tableScroll, BorderLayout.CENTER);
        fatherCenter.add(blueButton, BorderLayout.SOUTH);
        pane.add(fatherCenter);
    }

    private void addData() {
        Runnable doRun1 = new Runnable() {

            @Override
            public void run() {
                tableModel.resetTable();
                Vector<String> tbl = new Vector<String>();
                Vector<Object> tbl1 = new Vector<Object>();
                Random rnd = new Random();
                tbl.add("Integer");
                tbl.add("Double");
                tbl.add("Boolean");
                tbl.add("Boolean");
                tbl.add("String");
                tableModel.setColumnNames(tbl);
                for (int row = 0; row < 30; row++) {
                    tbl1 = null;
                    tbl1 = new Vector<Object>();
                    tbl1.addElement(row + 1);
                    tbl1.addElement(rnd.nextInt(25) + 3.14);
                    tbl1.addElement((row % 3 == 0) ? false : true);
                    tbl1.addElement((row % 5 == 0) ? false : true);
                    if (row % 7 == 0) {
                        tbl1.add(("Canc"));
                    } else if (row % 6 == 0) {
                        tbl1.add(("Del"));
                    } else {
                        tbl1.add(("New"));
                    }
                    tableModel.addRow(tbl1);
                }
                addTableListener();
            }
        };
        SwingUtilities.invokeLater(doRun1);
    }

    private void addTableListener() {
        tableModel.addTableModelListener(new TableModelListener() {

            @Override
            public void tableChanged(TableModelEvent tme) {
                if (tme.getType() == TableModelEvent.UPDATE) {
                    System.out.println("");
                    System.out.println("Cell " + tme.getFirstRow() + ", "
                            + tme.getColumn() + " changed. The new value: "
                            + tableModel.getValueAt(tme.getFirstRow(),
                            tme.getColumn()));
                }
            }
        });
    }

    public void valueChanged(ListSelectionEvent le) {
        int row = dialogTable.getSelectedRow();
        int col = dialogTable.getSelectedColumn();
        String str = "Selected Row(s): ";
        int[] rows = dialogTable.getSelectedRows();
        for (int i = 0; i < rows.length; i++) {
            str += rows[i] + " ";
        }
        str += "Selected Column(s): ";
        int[] cols = dialogTable.getSelectedColumns();
        for (int i = 0; i < cols.length; i++) {
            str += cols[i] + " ";
        }
        str += "Selected Cell: " + dialogTable.getSelectedRow() + ", " + dialogTable.getSelectedColumn();
        System.out.println(str);
        Object value = dialogTable.getValueAt(row, col);
        System.out.println(String.valueOf(value));
    }

    private void createAndShowGUI() {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout(10, 10));
        addComponentsToPane(frame.getContentPane());
        addData();
        frame.setLocation(150, 150);
        frame.setPreferredSize(new Dimension(400, 647));
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Forum osFrame = new Forum();
    }

    public Forum() {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }

    private class myTableModel extends AbstractTableModel {

        private static final long serialVersionUID = 1L;
        private Vector<Vector<Object>> data;
        private Vector<String> colNames;
        private boolean[] _columnsVisible = {true, true, true, true, true};

        myTableModel() {
            this.colNames = new Vector<String>();
            this.data = new Vector<Vector<Object>>();
        }

        myTableModel(Vector<String> colnames) {
            this.colNames = colnames;
            this.data = new Vector<Vector<Object>>();
        }

        public void resetTable() {
            this.colNames.removeAllElements();
            this.data.removeAllElements();
        }

        public void setColumnNames(Vector<String> colNames) {
            this.colNames = colNames;
            this.fireTableStructureChanged();
        }

        public void addRow(Vector<Object> data) {
            this.data.add(data);
            //this.fireTableDataChanged();
            //this.fireTableStructureChanged();
            this.fireTableRowsInserted(data.size() - 1, data.size() - 1);
        }

        public void removeRowAt(int row) {
            this.data.removeElementAt(row);
            //this.fireTableDataChanged();
            this.fireTableRowsDeleted(row - 1, data.size() - 1);
        }

        @Override
        public int getColumnCount() {
            return this.colNames.size();
        }

        @Override
        public Class<?> getColumnClass(int colNum) {
            switch (colNum) {
                case 0:
                    return Integer.class;
                case 1:
                    return Double.class;
                case 2:
                    return Boolean.class;
                case 3:
                    return Boolean.class;
                default:
                    return String.class;
            }
        }

        @Override
        public boolean isCellEditable(int row, int colNum) {
            switch (colNum) {
                case 2:
                    return false;
                default:
                    return true;
            }
        }

        @Override
        public String getColumnName(int colNum) {
            return this.colNames.get(colNum);
        }

        @Override
        public int getRowCount() {
            return this.data.size();
        }

        @Override
        public Object getValueAt(int row, int col) {
            Vector<Object> value = this.data.get(row);
            return value.get(col);
        }

        @Override
        public void setValueAt(Object newVal, int row, int col) {
            Vector<Object> aRow = data.elementAt(row);
            aRow.remove(col);
            aRow.insertElementAt(newVal, col);
            fireTableCellUpdated(row, col);
        }

        public void setColumnVisible(int index, boolean visible) {
            this._columnsVisible[index] = visible;
            this.fireTableStructureChanged();
        }
    }
}
Synchro answered 1/8, 2011 at 16:31 Comment(2)
The custom TableModel code is not the best as the addRow, removeRowAt methods fire the wrong event. You should be using fireTableRowInserted and fireTableRowsDeleted respectively. This is the most efficient as only affected rows in the table will be repainted. The fireTableStructureChanged is expensive as it will recreate the TableColumnModel along with all the TableColumns. This can be a problem if you have added any custom renderers or editor to the table as you would lose them.Gillespie
@Gillespie thanks for excelent and valuable commment, bump ... -> that's maybe my problem with implementation for prepareEditor(), but that's another story <- , I'll amend my postSynchro
D
0

It may sound wired myself answering to one of my questions. but I found another quck fix to my bug. but am not really sure about the reason. I call a epaint just before the validate and everything works fine:

deployTable.repaint();
deployTable.revalidate();

I think i have not really clear the difference within repaint and revalidate. Can anyone explain it to me?

Dedededen answered 2/8, 2011 at 7:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.