javaswingjtabletablecellrenderer

Adjust one cell in JTable instead of whole row


I have run into a slight issue and am struggling to resolve it. Basically what is happening is that I have a JTable which is being populated by an array that I get from an API call.
What I currently have is that if a device shows as online it will change GREEN, if offline, then a light-gray.
The problem is that it is affecting the entire ROW and not just the status CELL. I only want the status cell to highlight green. Any help would be really appreciated.

custTable = new javax.swing.JTable(model){

@Override
public Component prepareRenderer(TableCellRenderer renderer, int rowIndex,
    int columnIndex) {
    JComponent component = (JComponent) super.prepareRenderer(renderer, rowIndex, columnIndex);

    if(getValueAt(rowIndex,1).toString().equalsIgnoreCase("Online"))
    {
        component.setBackground(Color.GREEN);
    }
    else if(getValueAt(rowIndex,1).toString().equalsIgnoreCase("Offline"))
    {
        component.setBackground(Color.lightGray);
    }

    return component;
}

Screenshot


Solution

  • Don't override the prepareRenderer() method. Generally you would only override this method when you want the rendering to be effective for the enter row. This approach is useful because the rendering code is in one place and you don't have to create custom renderers for every column in the table.

    However, for specific rendering of a cell in a specific column you should create a custom renderer for the column.

    Read the section from the Swing tutorial on Using Custom Renderers for more information and examples.

    The tutorial example implement the TableCellRenderer interface. It may be easier to extend the default renderer:

    class ColorRenderer extends DefaultTableCellRenderer
    {
        @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 (!isSelected)
            {
                int viewColumn = convertColumnIndexToView(1)
                String value = getModel().getValueAt(rowIndex, viewColumn).toString();
    
                if ("Online".equalsIgnoreCase(value))
                    setBackground( Color.GREEN );
                else
                    setBackground( Color.lightgray );
    
                return this;
            }
        }
    }
    

    Note you should convert the column index in case the user has reorder the columns in the table.

    Then to use the render you can add it to individual columns using:

    TableCellRenderer colorRenderer = new ColorRenderer();
    table.getColumnModel().getColumn(1).setCellRenderer( colorRenderer );