2

I have 2 columns in jTable. First column itemname and second column is checkbox added column. I tried to add checkbox into jTable column but checkbox is getting added into all column cells.But i want to add checkbox only for corresponding cells of itemname column which has values in it.If itemname value is null that corresponding checkbox column also i want to set as null.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Soorya Thomas
  • 391
  • 1
  • 8
  • 23
  • for better help sooner post an [SSCCE](http://sscce.org/) – mKorbel Jun 22 '12 at 08:37
  • @mKorbel:i can't access above link.Can you help me.Thanks in advance. – Soorya Thomas Jun 22 '12 at 10:18
  • 3
    javastudent you are saying you have problems getting at http://sscce.org/ ? In any case @mKorbel means that you should show us your code in a format that is self-contained, i.e. shows the problem and we could run it at home. – Boro Jun 22 '12 at 11:11

1 Answers1

2

Using your own TableCellEditor and TableCellRenderer, you can decide to have whatever you want displayed. Here is an example where I "play" with the visibility of the checkbox every third row:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;

import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

public class TestTable {

    private JFrame f;
    private JTable table;

    private class MyCheckBoxRendererEditor extends JPanel implements TableCellRenderer, TableCellEditor, ActionListener {
        private JCheckBox checkbox;

        DefaultTableCellRenderer defaultRenderer;

        public MyCheckBoxRendererEditor() {
            defaultRenderer = new DefaultTableCellRenderer();
            checkbox = new JCheckBox();
            checkbox.setOpaque(false);
            checkbox.addActionListener(this);
            checkbox.setRequestFocusEnabled(false);
            setOpaque(true);
            add(checkbox);
            validate();
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            stopCellEditing();
        }

        @Override
        public Object getCellEditorValue() {
            return checkbox.isSelected();
        }

        @Override
        public boolean isCellEditable(EventObject anEvent) {
            return true;
        }

        @Override
        public boolean shouldSelectCell(EventObject anEvent) {
            return true;
        }

        @Override
        public boolean stopCellEditing() {
            for (CellEditorListener listener : getListeners(CellEditorListener.class)) {
                listener.editingStopped(new ChangeEvent(this));
            }
            return true;
        }

        @Override
        public void cancelCellEditing() {
            for (CellEditorListener listener : getListeners(CellEditorListener.class)) {
                listener.editingCanceled(new ChangeEvent(this));
            }
        }

        @Override
        public void addCellEditorListener(CellEditorListener l) {
            this.listenerList.add(CellEditorListener.class, l);
        }

        @Override
        public void removeCellEditorListener(CellEditorListener l) {
            this.listenerList.remove(CellEditorListener.class, l);
        }

        @Override
        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
            configure(table, value, true, true, row, column);
            return this;
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            configure(table, value, isSelected, hasFocus, row, column);
            return this;
        }

        private void configure(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            defaultRenderer.setBackground(null);
            defaultRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            MyObject myObject = ((MyTableModel) table.getModel()).getValueAt(row);
            checkbox.setVisible(myObject.getValue() != null);
            checkbox.setSelected((Boolean) value);
            setBackground(defaultRenderer.getBackground());
            setBorder(defaultRenderer.getBorder());
        }

    }

    private class MyObject {
        private final String value;
        private boolean checked;

        public MyObject(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }

        public boolean isChecked() {
            return checked;
        }

        public void setChecked(boolean checked) {
            this.checked = checked;
            System.err.println(value + " is " + checked);
        }
    }

    protected void initUI() {
        List<MyObject> data = new ArrayList<TestTable.MyObject>();
        for (int i = 0; i < 20; i++) {
            MyObject object = new MyObject(i % 3 == 1 ? null : "Row " + (i + 1));
            data.add(object);
        }
        table = new JTable(new MyTableModel(data));
        table.getColumnModel().getColumn(1).setCellEditor(new MyCheckBoxRendererEditor());
        table.getColumnModel().getColumn(1).setCellRenderer(new MyCheckBoxRendererEditor());
        table.setRowHeight(30);
        f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new JScrollPane(table), BorderLayout.CENTER);
        f.pack();
        f.setVisible(true);

    }

    public class MyTableModel extends AbstractTableModel {

        private List<MyObject> data;

        public MyTableModel(List<MyObject> data) {
            super();
            this.data = data;
        }

        @Override
        public int getColumnCount() {
            return 2;
        }

        @Override
        public int getRowCount() {
            return data.size();
        }

        public MyObject getValueAt(int row) {
            return data.get(row);
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            switch (columnIndex) {
            case 0:
                return getValueAt(rowIndex).getValue();
            case 1:
                return getValueAt(rowIndex).isChecked();
            }
            return null;
        }

        @Override
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
            if (columnIndex == 1) {
                getValueAt(rowIndex).setChecked((Boolean) aValue);
            }
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return columnIndex == 1 && getValueAt(rowIndex).getValue() != null;
        }

        @Override
        public Class<?> getColumnClass(int column) {
            switch (column) {
            case 0:
                return String.class;
            case 1:
                return Boolean.class;
            }
            return Object.class;
        }

        @Override
        public String getColumnName(int column) {
            switch (column) {
            case 0:
                return "Value";
            case 1:
                return "Checked";
            }
            return null;
        }

    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestTable().initUI();
            }
        });
    }

}
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • [what I understood](http://stackoverflow.com/questions/7045851/jtable-how-prepareeditor-works), but not sure from question, then I leave whatever here – mKorbel Jun 22 '12 at 14:54
  • 1
    +1 but requires `MyObject implements Comparable` if `setAutoCreateRowSorter(true)`. – trashgod Jun 22 '12 at 15:17