Postpone Event Queue after Focus Lost

2019-07-08 08:24发布

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.

2条回答
三岁会撩人
2楼-- · 2019-07-08 08:48

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.

查看更多
做自己的国王
3楼-- · 2019-07-08 09:00

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).

查看更多
登录 后发表回答