我正在尝试向JOptionPane
显示一个JTextField
,其中有一个初始焦点,并且,当用户按下ENTER时,我希望它在输入的文本中执行操作在文本字段中。
我做了一些广泛的搜索,但没有找到任何可以帮助我的东西。我将在此陈述我到目前为止所做的事情:
这就是我得到的
Object[] options = {"Option1",
"Option2"};
Object[] message = new Object[2];
message[0] = "Type in the number of the incident:";
JTextField incidentNumberTextField = new JTextField();
message[1] = incidentNumberTextField;
int n = JOptionPane.showOptionDialog(frame,
message,
"Open incident",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
message[1]);
if (n == -1) {
return;
}
到目前为止一切正常。当对话框出现时,焦点位于文本字段上。但是,当我输入文本并按Enter键时,它希望它自动触发" Option1"按钮。
我尝试过听众,但似乎我无法从内部访问非最终数据 - 即文本字段。
答案 0 :(得分:4)
基本上,你有几个问题需要互相争斗才能解决:-)
最后一个可以通过JTextField的自定义子类来解决,就像BasicOptionPaneUI用于inputDialog一样,它在最后显示 - 只有在解决前两个时才在optionPane上下文中使用。我没有看到一个完全令人满意的解决方案:将“消息”的概念与“选项”的概念混合,将optionPane混淆为而不是设置rootpane的默认按钮。所以最后,你最好不要使用第一个技巧,坚持使用“选项”概念,然后通过在字段的addNotify中请求转移来欺骗焦点。
@Override
public void addNotify() {
super.addNotify();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
requestFocus();
}
});
}
自定义JTextField,它不会吃某些keyStrokes。它被称为MultiplexingTextField,如果配置为执行此操作,则传递keyStrokes的处理:
public static class MultiplexingTextField extends JTextField {
private List<KeyStroke> strokes;
public MultiplexingTextField(int cols) {
super(cols);
}
/**
* Sets the KeyStrokes that will be additionally processed for
* ancestor bindings.
*/
public void addKeyStrokes(KeyStroke... keyStrokes) {
for (KeyStroke keyStroke : keyStrokes) {
getMultiplexingStrokes().add(keyStroke);
}
}
private List<KeyStroke> getMultiplexingStrokes() {
if (strokes == null) {
strokes = new ArrayList<KeyStroke>();
}
return strokes;
}
@Override
protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
int condition, boolean pressed) {
boolean processed = super.processKeyBinding(ks, e, condition,
pressed);
if (processed && condition != JComponent.WHEN_IN_FOCUSED_WINDOW
&& getMultiplexingStrokes().contains(ks)) {
// Returning false will allow further processing
// of the bindings, eg our parent Containers will get a
// crack at them.
return false;
}
return processed;
}
}
在受控环境中的使用:
Action fieldAction = new AbstractAction("fieldAction") {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("hello " + ((JTextComponent) e.getSource()).getText());
}
};
JTextField field = new JTextField("this is a normal field");
MultiplexingTextField multiplexing = new MultiplexingTextField(20);
multiplexing.addKeyStrokes(KeyStroke.getKeyStroke("ENTER"));
field.setAction(fieldAction);
multiplexing.setAction(fieldAction);
Action action = new AbstractAction("default button action") {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("hello - got default button");
}
};
JButton button = new JButton(action);
JPanel panel = new JPanel();
panel.add(field);
panel.add(multiplexing);
panel.add(button);
// this is swingx testing support, simply replace with normal frame creation
JXFrame frame = wrapInFrame(panel, "multiplex");
frame.getRootPane().setDefaultButton(button);