问题
I have a JTable
with a custom cell editor. The editor implements FocusListener
so I can check if the cell's contents is valid if the user clicks away from the cell.
I'd like to use a JOptionPane
within focusLost
(in the EventDispatchThread
) to allow the user to select whether to revert to an old value or accept an adjusted value.
Here's the problem; if the user is editing a cell, then clicks a button away from the table, the button's actionlisteners
are alerted before JOptionPane
has returned.
This is what I'd like to happen:
- User edits cell
- User clicks button
- Cell detects focus lost
- JOptionPane displayed and user selects action
- JOptionPane closes and cell's value set
- Button's actionListeners called
Instead, this is happening:
- User edits cell
- User clicks button
- Cell detects focus lost
- JOptionPane displayed and user selects action
- Button's actionListeners called
- JOptionPane closes and cell's value set
Is it possible to postpone the button's action events until after the JOptionPane
has closed?
From other threads, I've read that JDialog
does some magic to ensure event dispatching continues so the Dialog itself can handle events.
回答1:
From what I gather, you don't want the button's action-listener to activate at all, until AFTER the user selects the correct value from the JOptionPane.
To me it seems like the solution would be to set up a 'disabled' flag which goes up once the focusLost is triggered. Once the selection is made, the disabled flag goes down. When the button action is triggered, it checks if the form is disabled; if it is, it does nothing. If it isn't it continues as normal.
Notice the button event won't go automatically once the user selected something in the JOptionPane, but instead he will have to click the button again. To me this seems like better functionality then having the button 'clicked' again for him after he is required to change the form.
回答2:
Put your validation logic inside TableCellEditor#stopCellEditing()
, showing your dialog and returning false if the value is not valid.
To automatically stop table editing on focus lost, use table.putClientProperty("terminateEditOnFocusLost", true);
, but I don't think that will stop the buttons action listener from running. Instead I usually stop the table edit in the actionPerformed and do nothing when false is returned (or cancel editing when appropriate, for example if the action is to delete that table row).
来源:https://stackoverflow.com/questions/9275912/postpone-event-queue-after-focus-lost