I have a option dialog like this:
String[] options = ["Yes", "No"]; //button names
int n = JOptionPane.showOptionDialog(singleFrameService.getFrame(),
"Some Question?",
"",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null, //do not use a custom Icon
options, //the titles of buttons
options[0]); //default button title
//if press yes
if (n == JOptionPane.YES_OPTION){
//make some if pressed Yes
}
When I used mouse and press Yes/No - all work fine... But when I start use keyboard, press TAB to go to "No" button, and then press ENTER - work "Yes" option
It all depends on the look 'n feel, AFAIK. In your L&F, "Enter" means "press the default button" (which is Yes). Pressing the focused button is probably done by pressing the space bar.
This will make the uimanager handle the focused button. This will allow you to use both enter or space to select the focused button.
UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE);
I needed JOptionPane to respond to the return key the same way it responds to the space key and this was how I successfully went about it: I created a new instance of JOPtionPane and called its createDialog method to obtain it's dialog window.
Then I passed its dialog window to the listComponents(java.awt.Container) method below and that did the trick!
private static index=0;
private static void listComponents(java.awt.Container c){
if(c==null)return;
for(java.awt.Component cc:c.getComponents())
listComponents((java.awt.Container)cc);
if(c instanceof javax.swing.JButton){
buttons[index++]=(javax.swing.JButton)c;
javax.swing.InputMap inputMap=buttons[index-1].getInputMap(javax.swing.JComponent.WHEN_FOCUSED);
javax.swing.Action spaceAction=buttons[index-1].getActionMap().get(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_SPACE,0));
inputMap.put(javax.swing.KeyStroke
.getKeyStroke(java.awt.event.KeyEvent.VK_ENTER,0),spaceAction);
}
}
In addition to JB Nizet's answer I would like to mention that input handling in java goes this way, if I understand it well:
- The components that are in the focussed window
- The component that has focus
- The component that is an ancestor of the focussed container
All in reverse order of how they were added (I'm not 100% about that but that would be logical). Now, an inputEvent can be consumed. In this case, the JOptionPane registers that enter is pressed, and traverses through the collection of components that have actions bound to the input event. The yes
button, as the default button consumes this event so that no other components can do anything with it.
The solution to your problem is that you're going to have to create a custom JDialog. Give it a label for message, a placeholder for an icon, and two buttons. Now make the same constructor as the JOptionPane you are using and give each component the text/icon according to the parameters the constructor receives.
Addition to JB Nizet's answer I want to suggest if you can't using ENTER
key to access the Yes, No
button than trying to disabled that key. Here some example:
public class NewClass {
public static void main(String[] args) {
JFrame frame = new JFrame();
String[] options = {"Yes", "No"};
int n = JOptionPane.showOptionDialog(frame,
"Some Question? Press space bar to continue...",
"",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null, //do not use a custom Icon
options, //the titles of buttons
null); // disabled the ENTER Key
System.out.println(n);
if (n == JOptionPane.YES_OPTION) {
System.out.println("Yes");
} else {
System.out.println("No");
}
System.exit(1);
}
}
来源:https://stackoverflow.com/questions/10395181/joptionpane-yes-option-enter-on-each-button