2

I have left-aligned my cell renderers, but how do I left-align my cell editors? This happens when I edit one of the cells

sample

import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

public class TextPaneTest extends JFrame {

    public static void main(String args[]) {
        new TextPaneTest();
    }

    public TextPaneTest() {

        // Main panel
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());

        JTable table = new JTable() { 
            @Override
            public TableCellEditor getCellEditor(int row, int column) {
                if (column == 1)
                {
                    ////////////////////////
                    // What might go here //
                    ////////////////////////
                    return getDefaultEditor(Boolean.class);
                }
                return super.getCellEditor(row, column);
            }

            @Override
            public TableCellRenderer getCellRenderer(int row, int column) {
                if (column == 1)
                {
                    TableCellRenderer renderer = getDefaultRenderer(Boolean.class);
                    ((JCheckBox)renderer).setHorizontalAlignment(SwingConstants.LEFT);
                    return renderer;
                }
                return super.getCellRenderer(row, column);
            }
        };

        String[] columnNames = {"Name", "Value"};
        Object[][] data = {{"one", true}, {"two", true}};
        DefaultTableModel model = new DefaultTableModel(data, columnNames);     
        table.setModel(model);

        panel.add(table);
        // Add everything to the frame
        this.add(panel);
        this.setSize(300, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
}
MxLDevs
  • 19,048
  • 36
  • 123
  • 194

1 Answers1

2

As first step changing this condition:

if (column == 1)

by

if(getValueAt(row, column) instanceof Boolean)

will make your methods more flexible (think about 5 columns with booleans, you don't want to check for every column number to return default renderer/editor).

I would also suggest you make your own cell renderer extending from JCheckBox and set this as default cell renderer for Boolean class. It will avoid you make the alignment change inside getCellRenderer() method.

Note by defaultgetDefaultRenderer(Boolean.class) returns a JCheckBox but getDefaultEditor(Boolean.class) returns a javax.swing.JTable.BooleanEditor when the logic says it should be return a JCheckBox too. So maybe casting the default renderer could be a problem in some point.

I made it work this way:

JTable table = new JTable(dtm){
    @Override
    public TableCellEditor getCellEditor(int row, int column) {
        if(getValueAt(row, column) instanceof Boolean){
            return super.getDefaultEditor(Boolean.class);
        }
        return super.getCellEditor(row, column);
    }

    @Override
    public TableCellRenderer getCellRenderer(int row, int column) {
        if(getValueAt(row, column) instanceof Boolean){
            JCheckBox cb = (JCheckBox) getDefaultRenderer(Boolean.class);
            cb.setHorizontalAlignment(SwingConstants.LEFT);
            return getDefaultRenderer(Boolean.class);
        }

        return super.getCellRenderer(row, column);
    }
};

JCheckBox cb = new JCheckBox();
cb.setHorizontalAlignment(SwingConstants.LEFT);
TableCellEditor tce = new DefaultCellEditor(cb);        
table.setDefaultEditor(Boolean.class, tce);

As you can see the key is set a DefaultCellEditor starting from a JCheckBox as default cell editor for Boolean class.

Screenshot

enter image description here

SSCCE

Here's a complete SSCCE to test this:

import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.DefaultCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

public class Demo {

    private void initGUI(){

        DefaultTableModel dtm = new DefaultTableModel(new Object[]{"Property", "Value"}, 0);
        dtm.addRow(new Object[]{"Property 1", true});
        dtm.addRow(new Object[]{"Property 2", false});

        JTable table = new JTable(dtm){
            @Override
            public TableCellEditor getCellEditor(int row, int column) {
                if(getValueAt(row, column) instanceof Boolean){
                    return super.getDefaultEditor(Boolean.class);
                }
                return super.getCellEditor(row, column);
            }

            @Override
            public TableCellRenderer getCellRenderer(int row, int column) {
                if(getValueAt(row, column) instanceof Boolean){
                    JCheckBox cb = (JCheckBox) getDefaultRenderer(Boolean.class);
                    cb.setHorizontalAlignment(SwingConstants.LEFT);
                    return getDefaultRenderer(Boolean.class);
                }

                return super.getCellRenderer(row, column);
            }
        };

        JCheckBox cb = new JCheckBox();
        cb.setHorizontalAlignment(SwingConstants.LEFT);
        TableCellEditor tce = new DefaultCellEditor(cb);        
        table.setDefaultEditor(Boolean.class, tce);

        JScrollPane scrollPane = new JScrollPane(table);
        scrollPane.setPreferredSize(new Dimension(300,200));

        JPanel content = new JPanel(new BorderLayout());
        content.add(scrollPane);

        JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setContentPane(content);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);        
    }


    public static void main(String[] args) {        
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Demo().initGUI();
            }
        });
    }

}
dic19
  • 17,821
  • 6
  • 40
  • 69