user3271166
user3271166

Reputation: 623

Unable to use custom renderer

I am trying to create custom cell renderer for jTable. And I would admit, even with so much reading I havent really been able to understand how to add custom components as cell renderer. I want to add JCheckBox renderer.

So far I have tried this code:

import java.awt.Component;

import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

public class test extends JFrame {
    public static DefaultTableModel model = new DefaultTableModel();
    public static void main (String args[]){
    JTable table = new JTable();
    table.setDefaultRenderer(String.class, new CheckboxTableCellRenderer());
    table.setModel(model);
    model.addRow(new Object[] {"testData2","testData1"});
    JFrame frame = new JFrame();
    frame.add(list);
    frame.pack();
    frame.setVisible(true);
}



public static class CheckboxTableCellRenderer<E> extends JCheckBox implements
 TableCellRenderer {

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

     setFont(table.getFont());
     setText(String.valueOf(value));

     setBackground(table.getBackground());
     setForeground(table.getForeground());

     setSelected(isSelected);
     setEnabled(table.isEnabled());

     return this;
}

}
}

But no matter what row I try to add to model, it doesnt show any data in table.

Can anyone show me a correct way to do this?

Upvotes: 1

Views: 88

Answers (1)

Vlad
Vlad

Reputation: 18633

Working example:

import java.awt.Component;

import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.JScrollPane;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

public class test extends JFrame {
    public static DefaultTableModel model = new DefaultTableModel(0, 4) {
      public Class getColumnClass(int columnIndex) {
        if (columnIndex == 2 || columnIndex == 3) {
          return Boolean.class;
        } else {
          return Object.class;
        }
      }
    };
    public static void main (String args[]){
      JTable table = new JTable();
      table.setDefaultRenderer(Boolean.class, new CheckboxTableCellRenderer());
      model.addRow(new Object[] {"testData2","testData1",false,true});
      table.setModel(model);
      JFrame frame = new JFrame();
      frame.add(new JScrollPane(table));
      frame.setSize(640,480);
      frame.setVisible(true);
    }

    public static class CheckboxTableCellRenderer<E> extends JCheckBox implements
     TableCellRenderer {

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

           setFont(table.getFont());

            if (!isSelected) {
              setBackground(table.getBackground());
              setForeground(table.getForeground());
            } else {
              setBackground(table.getSelectionBackground());
              setForeground(table.getSelectionForeground());
            }


           setSelected((Boolean) value);
           setEnabled(table.isEnabled());

           return this;
      }

    }

}

You only want the custom renderer for Boolean.class, but DefaultTableModel only returns Object.class, hence an override for getColumnClass. Might also need to specify the number of columns, see the constructor call.

isSelected is not about the value in the cell but rather if the cell/row is selected and should be displayed in reverse (or otherwise) colors.

Also added a JScrollPane, might not be needed.

Editing still looks weird, you might need to define a custom editor as well but not sure.

Edit: if, as per @trashgod's suggestion, we just drop the setDefaultRenderer() call, it looks pretty good.

Upvotes: 3

Related Questions