我可以防止 JDialog 在 escape/enter 按下时关闭吗?
Can I keep a JDialog from closing on escape/enter press?
我创建了一个对话框来接受用户击键来更改菜单项的键绑定。我希望 enter 和 escape 成为用户可以绑定的键,但它们都关闭了对话框。那些新闻怎么能被拦截?
编辑:
使用 JOptionPane 和自定义组件创建对话框
GetKeyComponent comp = new GetKeyComponent(accels, menuItem);
Object[] array = { comp };
JOptionPane optionPane = new JOptionPane(array,
JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
Edit: dialog is created with JOptionPane and a custom component
一个解决方案:不要这样做。创建您自己的模态 JDialog,设置其 KeyBindings,然后使用它。例如,
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class JDialogTest {
private static void createAndShowGUI() {
final JFrame frame = new JFrame("JDialogTest");
JPanel panel = new JPanel();
panel.add(new JButton(new AbstractAction("Push Me") {
@Override
public void actionPerformed(ActionEvent arg0) {
final JTextArea textArea = new JTextArea(15, 30);
textArea.setFocusable(false);
JDialog dialog = new JDialog(frame, "Dialog", true);
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
JPanel contentPane = (JPanel) dialog.getContentPane();
InputMap inputMap = contentPane.getInputMap(condition);
ActionMap actionMap = contentPane.getActionMap();
KeyStroke enterKs = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
inputMap.put(enterKs, enterKs.toString());
actionMap.put(enterKs.toString(), new AbstractAction() {
@Override
public void actionPerformed(ActionEvent arg0) {
textArea.append("Enter pushed\n");
}
});
KeyStroke escKs = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
inputMap.put(escKs, escKs.toString());
actionMap.put(escKs.toString(), new AbstractAction() {
@Override
public void actionPerformed(ActionEvent arg0) {
textArea.append("Escape pushed\n");
}
});
dialog.add(new JScrollPane(textArea));
dialog.pack();
dialog.setVisible(true);
}
}));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
我创建了一个对话框来接受用户击键来更改菜单项的键绑定。我希望 enter 和 escape 成为用户可以绑定的键,但它们都关闭了对话框。那些新闻怎么能被拦截?
编辑: 使用 JOptionPane 和自定义组件创建对话框
GetKeyComponent comp = new GetKeyComponent(accels, menuItem);
Object[] array = { comp };
JOptionPane optionPane = new JOptionPane(array,
JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
Edit: dialog is created with JOptionPane and a custom component
一个解决方案:不要这样做。创建您自己的模态 JDialog,设置其 KeyBindings,然后使用它。例如,
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class JDialogTest {
private static void createAndShowGUI() {
final JFrame frame = new JFrame("JDialogTest");
JPanel panel = new JPanel();
panel.add(new JButton(new AbstractAction("Push Me") {
@Override
public void actionPerformed(ActionEvent arg0) {
final JTextArea textArea = new JTextArea(15, 30);
textArea.setFocusable(false);
JDialog dialog = new JDialog(frame, "Dialog", true);
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
JPanel contentPane = (JPanel) dialog.getContentPane();
InputMap inputMap = contentPane.getInputMap(condition);
ActionMap actionMap = contentPane.getActionMap();
KeyStroke enterKs = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
inputMap.put(enterKs, enterKs.toString());
actionMap.put(enterKs.toString(), new AbstractAction() {
@Override
public void actionPerformed(ActionEvent arg0) {
textArea.append("Enter pushed\n");
}
});
KeyStroke escKs = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
inputMap.put(escKs, escKs.toString());
actionMap.put(escKs.toString(), new AbstractAction() {
@Override
public void actionPerformed(ActionEvent arg0) {
textArea.append("Escape pushed\n");
}
});
dialog.add(new JScrollPane(textArea));
dialog.pack();
dialog.setVisible(true);
}
}));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}