Utilizzo di setValueAt per ricreare caselle di controllo mutuamente esclusive

Ho un JTable utilizzando un DefaultTableModel personalizzato che ha alcuni Booleani nell’ultima colonna (visualizzati come caselle di spunta).

Quando aggiungo un MouseListener per recuperare il valore di ciò che è stato cliccato, sembra che la commutazione delle caselle di spunta non avvenga più.

// As soon as this is used in the component // that is using the JTable, the toggling stops table.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent evt) { int col = table.getSelectedColumn(); int row = table.getSelectedRow(); Object o = table.getModel().getValueAt(row, col); 

Suppongo che l’evento venga consumato dall’ascoltatore. Cosa posso aggiungere al codice MouseListener per ripristinare il comportamento di commutazione?

Modificare:

Oops, sembra che il problema risieda nel mio override:

 @Override public void setValueAt(Object aValue, int row, int column) { // Attempt at mutually exclusive checkboxes if( column == 2 ){ // Starts at 0. Seek an alternative solution to avoid hardcoding? // Algorithm: cycle through List to set other Booleans to false // Uses entities. Is there another way of getting the number of rows from model? List myEntities = this.getDatas(); for( int i = 0; i < myEntities.size(); i++ ){ if( i != row ){ // Make sure this calls parent super.setValueAt( false , i, 2); } } } else { super.setValueAt(aValue, row, column); // Call parent class } } 

Non aggiungere il tuo MouseListener . setValueAt() invece setValueAt() in TableModel per vedere il nuovo valore impostato dall’editor predefinito per Boolean.class .

Addendum: ecco un punto . Per convenienza, cancella semplicemente tutte le voci in CHECK_COL , imposta il nuovo valore e condiziona il pulsante di conseguenza.

Immagine di CheckOne

 import java.awt.*; import javax.swing.*; import javax.swing.table.DefaultTableModel; /** * @see http://stackoverflow.com/questions/7920068 * @see http://stackoverflow.com/questions/4526779 */ public class CheckOne extends JPanel { private static final int CHECK_COL = 1; private static final Object[][] DATA = { {"One", Boolean.FALSE}, {"Two", Boolean.FALSE}, {"Three", Boolean.FALSE}, {"Four", Boolean.FALSE}, {"Five", Boolean.FALSE}, {"Six", Boolean.FALSE}, {"Seven", Boolean.FALSE}, {"Eight", Boolean.FALSE}, {"Nine", Boolean.FALSE}, {"Ten", Boolean.FALSE}}; private static final String[] COLUMNS = {"Number", "CheckBox"}; private DataModel dataModel = new DataModel(DATA, COLUMNS); private JTable table = new JTable(dataModel); private ControlPanel cp = new ControlPanel(); public CheckOne() { super(new BorderLayout()); this.add(new JScrollPane(table)); this.add(cp, BorderLayout.SOUTH); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); table.setPreferredScrollableViewportSize(new Dimension(250, 175)); } private class DataModel extends DefaultTableModel { public DataModel(Object[][] data, Object[] columnNames) { super(data, columnNames); } @Override public void setValueAt(Object aValue, int row, int col) { if (col == CHECK_COL) { for (int r = 0; r < getRowCount(); r++) { super.setValueAt(false, r, CHECK_COL); } } super.setValueAt(aValue, row, col); cp.button.setEnabled(any()); } private boolean any() { boolean result = false; for (int r = 0; r < getRowCount(); r++) { Boolean b = (Boolean) getValueAt(r, CHECK_COL); result |= b; } return result; } @Override public Class getColumnClass(int col) { if (col == CHECK_COL) { return getValueAt(0, CHECK_COL).getClass(); } return super.getColumnClass(col); } @Override public boolean isCellEditable(int row, int col) { return col == CHECK_COL; } } private class ControlPanel extends JPanel { JButton button = new JButton("Button"); public ControlPanel() { button.setEnabled(false); this.add(new JLabel("Selection:")); this.add(button); } } private static void createAndShowUI() { JFrame frame = new JFrame("CheckOne"); frame.add(new CheckOne()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { createAndShowUI(); } }); } }