Manohar
Manohar

Reputation: 19

Dynamically change the background color of a JTable cell

I want to change cell background color of JTable and want to fetch data from MySQL database.

I am using a data table in MySQL which has a status field. If the status is 1 then cell background color should be red and if the status is 0 then it should change to red.

Upvotes: 1

Views: 2177

Answers (3)

Manohar
Manohar

Reputation: 19

//This is the code which I have used to change jtable cell background color dynamically
[green color indicates empty(free) cell and red color indicates occupied cells][1]
 int row, col, row1, column;
    TableCellRenderer renderer;
    private static final int STATUS_COL = 1;
String host = "jdbc:mysql://localhost/your_database";
        String username = "root";
        String password = "";
        Statement stmt = null;
try {
            Class.forName("com.mysql.jdbc.Driver");
            Connection connect = DriverManager.getConnection(host, username, password);
            stmt = connect.createStatement();
            String sql = "your query";
            ResultSet rs = stmt.executeQuery(sql);
            ResultSetMetaData meta = rs.getMetaData();
            Object[][] data = new Object[10][2];
            DefaultTableModel model = new DefaultTableModel(data, col);
            jTable1.setModel(DbUtils.resultSetToTableModel(rs));
            rs = stmt.executeQuery(sql);
 int rowCnt = 0;
              try{

       rs = stmt.executeQuery(sql);
       if(rs.last()){
           rowCnt = rs.getRow();
       } 
    } catch (Exception e){
       System.out.println("Error getting row count");
       e.printStackTrace();
    }

            int nCol = rs.getMetaData().getColumnCount();
            List<String[]> table = new ArrayList<>();
String[] row = new String[nCol];
for(int l=1; l<rowCnt; l++)
{
    for (int iCol = 1; iCol <= nCol; iCol++) {
                    Object obj = rs.getObject(iCol);
                    row[iCol - 1] = (obj == null) ? null : obj.toString();
jTable1.setDefaultRenderer(Object.class, new EntryCellRender());
 }
                table.add(row);
}
 } catch (Exception e) {
            System.out.println(e);
        }
    }
public class EntryCellRender extends DefaultTableCellRenderer {

    private final Color alt2 = Color.RED;
    private final Color alt1 = Color.GREEN;
    private final Color invalidStatus = Color.RED;

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        Component cr = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if ("".equals(table.getValueAt(row, col))) {
             setBackground(alt1);
           } else {
               setBackground(alt2);
           }

        return cr;
    }

    private Color colorAlternator(int row) {
        if ((row % 2) == 0) {
            return alt1;
        } else {
            return alt2;
        }
    }
}   

    enter code here

  [1]: https://i.sstatic.net/Fi4LF.png

Upvotes: 0

XtremeBaumer
XtremeBaumer

Reputation: 6435

id suggest a custom cell renderer to achieve what you want to.

public class CellRenderer extends DefaultTableCellRenderer {

    private static final long serialVersionUID = 1L;

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

        if (column == /*your column number goes here*/) {
            this.setValue(table.getValueAt(row, column));
            this.setBackground(Color.RED);
        }
        return this;
    }
}

before you set the color, you can check the value if its 0 or 1 and then change the color if it is what you want

How I created and filled/refilled a JTable with data from a database:

Table:

private void createTable(Container pane) {
    Object[] namen = { "Datum", "Kategorie", "Essen", "Preise Intern", "Preise Extern" };
    model = new DefaultTableModel(namen, 0);
    table = new JTable(model) {

        public boolean isCellEditable(int x, int y) {
            return false;
        }
    };
    Dimension minimumSize = new Dimension(1000, 500);
    table.setPreferredScrollableViewportSize(minimumSize);
    TableRowSorter<DefaultTableModel> sorter = new TableRowSorter<DefaultTableModel>(model);
    table.setRowSorter(sorter);

    sorter.setComparator(3, Sorter.getComparator());
    sorter.setComparator(4, Sorter.getComparator());
    table.getColumnModel().getColumn(3).setCellRenderer(new CellRenderer()); //custom cell renderer
    table.getColumnModel().getColumn(4).setCellRenderer(new CellRenderer()); //custom cell renderer

    JScrollPane sp = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
}

and how i filled it:

void refreshTableContent(Vector<Gericht> v) {
    for (int i = table.getRowCount() - 1; i >= 0; i--) {
        model.removeRow(i);
    }
    fillTable(v);
}

void fillTable(Vector<Gericht> v) {
    for (int i = 0; i < v.size(); i++) {
        Gericht g = v.get(i);
        Vector<Object> vhelp = new Vector<>();
        vhelp.add(df.format(g.getDate()));
        vhelp.add(g.getClassification());
        vhelp.add(g.getName());
        vhelp.add(g.getPreisIntern());
        vhelp.add(g.getPreisExtern());
        model.addRow(vhelp);
    }
}

model is a DefaultTableModel on which you add and delete data. at every refill, i first delete all rows and then add them new. this is probably not the best solution but it works

the model is a meal in this case which has several fields. so i created a vector of my own object and then created a helping vector and stored the values of one meal in it. then i added the vector as row to the JTable and the next meal was stored in the helping vector.

I hope you can understand what i did here

Upvotes: 2

Abra
Abra

Reputation: 20914

As XtremeBaumer suggests, a custom cell renderer is a standard way to achieve what you want. Just remember that only one (1) instance of the cell renderer class is created and is used to render all the JTable cells.
Good luck!

Upvotes: -1

Related Questions