问题
I found this forum thread which suggests overriding ListSelectionModel to prevent rows from being selected.
I would like to prevent selection changes when there are unsaved changes (external to the table) for the currently selected item UNTIL the user confirms the discard. Something like:
public class confirmSelectionChange extends DefaultListSelectionModel {
public void setSelectionInterval(int index0, int index1) {
if (unsavedChanges()) {
super.setSelectionInterval(int index0, int index1);
}
}
private boolean unsavedChanges() {
if (noUnsavedChangesExist) {
return true;
}
// Present modal dialog: save, discard cancel
if (dialogAnswer == SAVE) {
// save changes
return true;
} else if (dialogAnswer == DISCARD) {
return true;
} else {
return false;
}
}
}
Is it possible to insert blocking code in the middle of ListSelectionModel changes? Is there a better way to intercept selection change events?
I'm already listening for them but the change has already happened by then.
回答1:
My final solution (thanks in part to this code guru) was to create an anonymous inner class that extends JTable and overrides changeSelection()
. Tried a separate class since I read that some people don't think anonymous inner classes are good OO design but I needed to know about the editing state plus I had to call save/discard methods. Who needs encapsulation when it's your own code anyway? ;-)
jTableMemberList = new JTable() {
public void changeSelection(int rowIndex, int columnIndex, boolean toggle,
boolean extend) {
// Member is being edited and they've clicked on a DIFFERENT row (this
// method gets called even when the selection isn't actually changing)
if (editModeIsActive && getSelectedRow() != rowIndex) {
// User was editing, now they're trying to move away without saving
Object[] options = {"Save", "Discard", "Cancel"};
int n = JOptionPane.showOptionDialog(this,
"There are unsaved changes for the "
+ "currently selected member.\n\n"
+ "Would you like to save them?",
"Save changes?",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE,
null,
options,
options[0]);
if (n == JOptionPane.YES_OPTION) {
saveChanges();
} else if (n == JOptionPane.NO_OPTION) {
discardChanges();
} else {
// Exit without passing call on to super
return;
}
}
// make the selection change
super.changeSelection(rowIndex, columnIndex, toggle, extend);
}
};
This solution seems to work so far but I haven't tested it extensively. There may be bugs or gotcha's lurking in one of the dark corners of this code...
Hope it helps someone else!
来源:https://stackoverflow.com/questions/3059489/intercept-jtable-selection-change-events