5

hi i am new in java jtable cellrendered. I am looking for a way that works in my program but i dont have any luck finding it. Here is my Jtable

Employee ID   |   Name     |   Status    |   Position
  00565651        Roger       Active        Manager
  00565652        Gina        Active        Crew
  00565652        Alex        Inactive      Crew
  00565652        Seph        Active        Manager    

the data came from ms access database but i want to change the background/foreground of the rows which has a value of "inactive" in status column. I found many examples in the internet but all of it is not possible in my program. Can someone help me? This is my model

String[] columnNames = {"Employee ID","Name", "Status", "Position"};
DefaultTableModel model = new DefaultTableModel(columnNames, 0);

and this is the way to create my table and how i am fetching data from database

public MyList(){//my constructor
    frame();
    loadListFromDB();
}
public void frame(){//
   //codes for frame setsize,titles etc...
   tblList = new JTable();
   tblList.getTableHeader().setPreferredSize(new Dimension(100, 40));
   tblList.getTableHeader().setFont(new Font("SansSerif", Font.BOLD, 25));
   tblList.setAutoCreateRowSorter(true);
   tblList.setModel(model);
   scrollPane.setViewportView(tblList);
   loadListFromDB();

}
public void loadListFromDB(){
   String sql = "SELECT emp_id,lname,fname,positional_status from tblEmployee";
    try{
        PreparedStatement ps = conn.prepareStatement(sql);
        ResultSet rs = ps.executeQuery();
        while (rs.next()){
            Vector row = new Vector();
            for (int i = 1; i <= 4; i++){
                row.addElement( rs.getObject(i) );
            }
            model.addRow(row);
        }
    }catch(Exception err){
        //for error code
    }
}

How am i suppose to add the tableredered in this way?Can anyone give simple example to change the color of row? Thanks in advance.. My program stop in this problem.

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
Lileth Hernandez
  • 61
  • 1
  • 1
  • 3
  • possible duplicate of [How do I set the JTable column and row color?](http://stackoverflow.com/questions/3548986/how-do-i-set-the-jtable-column-and-row-color) – DavidPostill Jul 20 '14 at 07:32
  • but the data were just initialized from the beginning, my data came from database, i dont know how to put my data in string[][] base on your example. – Lileth Hernandez Jul 20 '14 at 08:16
  • You issue is not about putting the data in the table but changing the row colour. You should be looking at the `TableCellRenderer` part of the example - and add rendering to your table. – DavidPostill Jul 20 '14 at 08:56
  • You could also take a look at [Table Row Rendering](http://tips4java.wordpress.com/2010/01/24/table-row-rendering/) – DavidPostill Jul 20 '14 at 08:58
  • The data source is irrelevant; here's another [example](http://stackoverflow.com/a/17164751/230513). – trashgod Jul 20 '14 at 08:59

1 Answers1

19

"i want to change the background/foreground of the rows which has a value of "inactive" in status column"

It's really just a matter of getting the value from table/model. if the status for that row is inactive, then set the background/foreground for every every cell in that row. Since the renderer is rendered for every cell, then basically you need to get the value of the [row][statusColumn], and that will be the status value for each row. Something like

table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer(){
    @Override
    public Component getTableCellRendererComponent(JTable table,
            Object value, boolean isSelected, boolean hasFocus, int row, int col) {

        super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);

        String status = (String)table.getModel().getValueAt(row, STATUS_COL);
        if ("active".equals(status)) {
            setBackground(Color.BLACK);
            setForeground(Color.WHITE);
        } else {
            setBackground(table.getBackground());
            setForeground(table.getForeground());
        }       
        return this;
    }   
});

Here's a simple example

enter image description here

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;

import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

public class TableRowDemo {

    private static final int STATUS_COL = 1;

    private static JTable getTable() {
        final String[] cols = {"col 1", "status", "col 3"};
        final String[][] data = {
                {"data", "active", "data"},
                {"data", "inactive", "data"},
                {"data", "inactive", "data"},
                {"data", "active", "data"}
        };
        DefaultTableModel model = new DefaultTableModel(data, cols);
        return new JTable(model) {
            @Override
            public Dimension getPreferredScrollableViewportSize() {
                return new Dimension(350, 150);
            }
        };
    }

    private static JTable getNewRenderedTable(final JTable table) {
        table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer(){
            @Override
            public Component getTableCellRendererComponent(JTable table,
                    Object value, boolean isSelected, boolean hasFocus, int row, int col) {
                super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
                String status = (String)table.getModel().getValueAt(row, STATUS_COL);
                if ("active".equals(status)) {
                    setBackground(Color.BLACK);
                    setForeground(Color.WHITE);
                } else {
                    setBackground(table.getBackground());
                    setForeground(table.getForeground());
                }       
                return this;
            }   
        });
        return table;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                JOptionPane.showMessageDialog(null, new JScrollPane(getNewRenderedTable(getTable())));
            }
        });
    }
}

Another option is to @Override prepareRenderer of the table. It will give you the same result.

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;

import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

public class TableRowDemo {

    private static final int STATUS_COL = 1;

    private static JTable getTable() {
        final String[] cols = {"col 1", "status", "col 3"};
        final String[][] data = {
                {"data", "active", "data"},
                {"data", "inactive", "data"},
                {"data", "inactive", "data"},
                {"data", "active", "data"}
        };
        DefaultTableModel model = new DefaultTableModel(data, cols);
        return new JTable(model) {
            @Override
            public Dimension getPreferredScrollableViewportSize() {
                return new Dimension(350, 150);
            }
            @Override
            public Component prepareRenderer(TableCellRenderer renderer, int row, int col) {
                Component c = super.prepareRenderer(renderer, row, col);
                String status = (String)getValueAt(row, STATUS_COL);
                if ("active".equals(status)) {
                    c.setBackground(Color.BLACK);
                    c.setForeground(Color.WHITE);
                } else {
                    c.setBackground(super.getBackground());
                    c.setForeground(super.getForeground());
                }
                return c;
            }
        };
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                JOptionPane.showMessageDialog(null, new JScrollPane(getTable()));
            }
        });
    }
}
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • Great answer I was looking for that. can we change the Table's Headers Style at the same time? – Mohammed Mohammed Dec 10 '14 at 19:23
  • @peeskillet how can the prepare renderer method be modified to change the column instead of the row's background colour? – Aequitas Aug 13 '15 at 03:27
  • 1
    @peeskillet when I used your code, the selection of my table changed; it was set to select row now it selects a cell, also the color of the selected cell changed, not the default color anymore – Amr Saber Mar 17 '17 at 01:56
  • i get Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at the line of getting the value of row, `String entry = (String) table.getModel().getValueAt(row, 2)`, any help please, thanks. – Hachachin May 10 '17 at 09:16
  • In the `getTableCellRendererComponent` method, does it make a difference whether I (a) simply invoke `super.getTableCellRendererComponent` and then make my format changes by invoking methods of `super` or `this` and then return `this` (as this answer does) or (b) declare a new `Component x = super.getTableCellRendererComponent` and then make the format changes to `x` and return `x`? – Candamir Jul 27 '17 at 13:44