1

I am using a custom CellEditor in a column

UPDATE: added a SSCCE

public class TestJFrame extends javax.swing.JFrame {

    public TestJFrame() {
        initComponents();
        jTable1.getTableHeader().addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(final MouseEvent e) {
                final JTableHeader tableHeader = (JTableHeader) e.getSource();
                final JTable table = tableHeader.getTable();
                final int column = tableHeader.columnAtPoint(e.getPoint());
                if (column == 1) {
                    TableCellEditor editor = table.getColumnModel()
                                                  .getColumn(column)
                                                  .getCellEditor();
                    for (int row = 0; row < table.getModel().getRowCount(); row++) {
                        if (table.getModel().isCellEditable(row, column)) {
                            editor.getTableCellEditorComponent(table, (e.getButton() == MouseEvent.BUTTON1),
                                                               false,
                                                               row,
                                                               column);
                            tableHeader.getTable().setValueAt((e.getButton() == MouseEvent.BUTTON1),
                                                              row,
                                                              column);
                        }
                    }
                }
            }
        });
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jTable1.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null},
                {null, null},
                {null, null}
            },
            new String [] {
                "name", "click me"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.Boolean.class
            };
            boolean[] canEdit = new boolean [] {
                false, true
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jScrollPane1.setViewportView(jTable1);
        if (jTable1.getColumnModel().getColumnCount() > 0) {
            jTable1.getColumnModel().getColumn(0).setResizable(false);
            jTable1.getColumnModel().getColumn(0).setPreferredWidth(100);
            jTable1.getColumnModel().getColumn(1).setCellEditor(new SwitchCellEditor(new EnableCheckbox(jTable1), jTable1));
        }

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 91, Short.MAX_VALUE)
                .addGap(0, 0, 0))
        );

        pack();
    }// </editor-fold>                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(TestJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(TestJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(TestJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(TestJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new TestJFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable jTable1;
    // End of variables declaration                   

    private static class EnableCheckbox extends JCheckBox {

        public EnableCheckbox(final JTable table) {
            addItemListener(new EnableCheckboxItemListenerImpl(table));
    }

        private final class EnableCheckboxItemListenerImpl implements ItemListener {

            private final JTable _table;

            public EnableCheckboxItemListenerImpl(final JTable table) {
                _table = table;

            }

            @Override
            public void itemStateChanged(ItemEvent e) {
                final JCheckBox checkBox = (JCheckBox) e.getSource();
                final int selectedRow = _table.rowAtPoint(checkBox.getLocation());
                final int selectedColumn = _table.columnAtPoint(checkBox.getLocation());

                // doStuff                
            }
        }
    }

    private class SwitchCellEditor extends DefaultCellEditor {

        private final JTable _table;
        private final JCheckBox _checkBox;

        public SwitchCellEditor(final JCheckBox checkBox, final JTable table) {
            super(checkBox);
            _checkBox = checkBox;
            _table = table;
        }

        @Override
        public final Component getTableCellEditorComponent(
                final JTable table,
                final Object value,
                final boolean isSelected,
                final int row,
                final int column) {

            Rectangle r = _table.getCellRect(row, column, false);

            if (_checkBox != null) {
                _checkBox.setLocation(new Point(r.x, r.y + r.height));
                return super.getTableCellEditorComponent(table, value, isSelected, row, column);
            }

            return super.getTableCellEditorComponent(table, value, isSelected, row, column);
        }
    }
}

The itemStateChanged method is only called on the first iteration step, but not on the following iteration steps.

Why is it behaving like that and how can I make it call itemStateChanged on each iteration step?

Cœur
  • 37,241
  • 25
  • 195
  • 267
mrt181
  • 5,080
  • 8
  • 66
  • 86
  • 1. depends of value stored in XxxTableModel, 2. XxxListener isn't neccessary, cant see reason to notify the clouds in the sky, 3. JTable/XxxTableModel knows JCheckBox as renderer/editors Component, , 4. please whats reason for editor in JTableHeader (isnt right place for editor) and in this form, a few times here and without side effects, 5. be sure that 99,99 pct of readers don't understand the code nor attn description, 6. for better help sooner post an SSCCE/MCVE, short, runnable, compilable with hardcoded value in local variable for JTable/XxxTableModel – mKorbel Jun 13 '14 at 08:38
  • When I click on the TableHeader, I want to select/deselct all checkboxes in the rows. – mrt181 Jun 13 '14 at 08:49
  • ( select/deselct all checkboxes in the rows) TableHeader or RowHeader ??? – mKorbel Jun 13 '14 at 08:50
  • 1
    For [example](http://stackoverflow.com/a/7137801/230513). – trashgod Jun 13 '14 at 08:55
  • Changed code to be a SSCCE – mrt181 Jun 13 '14 at 09:36
  • @trashgod your implementation sets the value in the table whenever itemStateChanged is called for the header, but it does not call itemStateChanged for each editor in each row. – mrt181 Jun 13 '14 at 10:08

1 Answers1

1

Your implementation … does not call itemStateChanged for each editor in each row.

Exactly. JTable uses the flyweight pattern for editors, updating the TableModel only after the editor concludes. If you want to see the editor's state change, you can either

  • Use the approach in the example cited here, in which the editor listens to the JCheckBox used by the corresponding renderer.

  • Add a CellEditorListener, mentioned here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045