user1353285
user1353285

Reputation: 191

JTable boolean values not updating when using JOptionPane

I'm trying to write a bit of code that can allow the user to fill in text fields by clicking on boolean cells in a JTable.

image

I can get the program to enter the data from the table into a text-field but my current method of doing this involves a JOptionPane which for some strange reason stops the table from changing the check-box values (i.e. the check-box doesn't change from black to ticked). Not only this but the selection doesn't update so the value in the last column remains false, even though the selection should switch it to true.

I think it might be something to do with the JOptionPane somehow overriding the selection event, but I don't know enough about the JOptionPane object to say how. My code is:

table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
ListSelectionModel selectionModel = table.getSelectionModel();
selectionModel.addListSelectionListener(new ListSelectionListener() {

    public void valueChanged(ListSelectionEvent e) {
        ListSelectionModel lsm = (ListSelectionModel) e.getSource();
        if (lsm.isSelectionEmpty()) {
            //no rows are selected do nothing
        } else {
            //First find the row clicked
            int selectedRow = lsm.getLeadSelectionIndex();
            /*
                * put a popup here to ask the user which peak to associate
                * the energy with.
                */
            System.out.println(selectedRow);
            //Get user to associate with a peak
            availablePeaks = getAvailablePeaks();
            String returnVal = (String) JOptionPane.showInputDialog(
                null,
                "Select the peak:",
                "Peak Matching",
                JOptionPane.QUESTION_MESSAGE,
                null,
                availablePeaks, null);
            System.out.println(returnVal);
            //Determine the selection
            int index = 0;
            for (int i = 0; i < availablePeaks.length; i++) {
                if (availablePeaks[i] == returnVal) {
                    index = i;
                } else {
                }
            }
            //Set the peak value in the peak specifier to the energy in the row
            double energy = (Double) table.getValueAt(selectedRow, 0);
            System.out.println(energy);
            frame.getPeakSetter().getPeakSpecifiers()[index].setEnergy(energy);
            frame.getPeakSetter().getPeakSpecifiers()[index].getTextField().setText("" + energy);
        }
    }
});

Does anyone know why a JOptionPane in the ListSelectionListener would stop the table from updating the check-boxes?

Thanks!

Upvotes: 1

Views: 453

Answers (1)

trashgod
trashgod

Reputation: 205875

I assume that your model returns true for isCellEditable() and that getColumnClass() returns Boolean.class for the JCheckBox column. This enables the default rednerer/editor, listed here.

It looks like the gesture of selecting the row is bringing up the dialog. It's not clear how this prevents the DefaultCellEditor from concluding; it works for me. As you are not checking getValueIsAdjusting(), I'm surprised you don't see two ListSelectionEvent instances.

In any case, bringing up a dialog each time the selection changes seems cumbersome. Several alternatives are possible:

  • Keep the ListSelectionListener, make the cell non-editable by returning false from isCellEditable(), and set its value in the model only if the dialog concludes successfully.

  • Drop the ListSelectionListener in favor of a JButton editor, shown here.

  • Drop the ListSelectionListener in favor of a custom CellEditor, as outlined below.

    table.setDefaultEditor(Boolean.class, new DefaultCellEditor(new JCheckBox()) {
    
        @Override
        public boolean stopCellEditing() {
            String value = JOptionPane.showInputDialog(...);
            ...
            return super.stopCellEditing();
        }
    });
    

Upvotes: 2

Related Questions