Search code examples
javaswingjtablejcheckboxabstracttablemodel

JTable Boolean.class


import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;

class ColorTableModel extends AbstractTableModel {

  Object rowData[][] = { { "value1", Boolean.FALSE },
      { "value1", Boolean.FALSE }, { "value1", Boolean.FALSE },
      { "value1", Boolean.FALSE}, { "value1", Boolean.FALSE }, };

  String columnNames[] = { "English", "Boolean" };

  public int getColumnCount() {
    return columnNames.length;
  }

  public String getColumnName(int column) {
    return columnNames[column];
  }

  public int getRowCount() {
    return rowData.length;
  }

  public Object getValueAt(int row, int column) {
    return rowData[row][column];
  }

  public Class getColumnClass(int column) {
    return (getValueAt(0, column).getClass());
  }

  public void setValueAt(Object value, int row, int column) {
    rowData[row][column] = value;
  }

  public boolean isCellEditable(int row, int column) {
    return (column != 0);
  }
}

public class EditableColorColumn {

  public static void main(String args[]) {
    JFrame frame = new JFrame("Editable Color Table");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    TableModel model = new ColorTableModel();
    JTable table = new JTable(model);
    // TableColumn column = table.getColumnModel().getColumn(3);
    // column.setCellRenderer(renderer);
    // column.setCellEditor(editor);

    JScrollPane scrollPane = new JScrollPane(table);
    frame.add(scrollPane, BorderLayout.CENTER);
    frame.setSize(400, 150);
    frame.setVisible(true);
  }

I would like to get the value of column one if I ticked the corresponding row. I have read a lot about this, but I can't just put it to code. Can you code a some one?

Sample scenario, when I ticked row1 checkbox, it will system.out.println() with a result of value1.


Solution

  • Your implementation of setValueAt() in your AbstractTableModel fails to fire the event that would notify listeners of the change:

    @Override
    public void setValueAt(Object value, int row, int column) {
        rowData[row][column] = value;
        fireTableCellUpdated(row, column);
    }
    

    Once that is corrected, a TableModelListener will see each change. Try commenting out the fireTableCellUpdated() line to see the difference.

    In addition:

    Code:

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.event.TableModelEvent;
    import javax.swing.event.TableModelListener;
    import javax.swing.table.AbstractTableModel;
    import javax.swing.table.TableModel;
    
    /**
     * @see https://stackoverflow.com/q/13497276/230513
     */
    public class EditableColorColumn {
    
        public static void main(String args[]) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new EditableColorColumn().display();
                }
            });
        }
    
        private void display() {
            JFrame frame = new JFrame("Editable Color Table");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            final TableModel model = new ColorTableModel();
            JTable table = new JTable(model);
            table.setPreferredScrollableViewportSize(new Dimension(400, 150));
            table.getModel().addTableModelListener(new TableModelListener() {
    
                @Override
                public void tableChanged(TableModelEvent e) {
                    System.out.println(model.getValueAt(e.getFirstRow(), 0)
                        + " " + model.getValueAt(e.getFirstRow(), 1));
                }
            });
    
            frame.add(new JScrollPane(table), BorderLayout.CENTER);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        private static class ColorTableModel extends AbstractTableModel {
    
            String columnNames[] = {"English", "Boolean"};
            Object rowData[][] = {
                {"value1", Boolean.FALSE},
                {"value2", Boolean.TRUE},
                {"value3", Boolean.FALSE},
                {"value4", Boolean.TRUE},
                {"value5", Boolean.FALSE},};
    
            @Override
            public int getColumnCount() {
                return columnNames.length;
            }
    
            @Override
            public String getColumnName(int column) {
                return columnNames[column];
            }
    
            @Override
            public int getRowCount() {
                return rowData.length;
            }
    
            @Override
            public Object getValueAt(int row, int column) {
                return rowData[row][column];
            }
    
            @Override
            public Class getColumnClass(int column) {
                return (getValueAt(0, column).getClass());
            }
    
            @Override
            public void setValueAt(Object value, int row, int column) {
                rowData[row][column] = value;
                fireTableCellUpdated(row, column);
            }
    
            @Override
            public boolean isCellEditable(int row, int column) {
                return (column != 0);
            }
        }
    }