java - JOptionPane 元素之间的交替焦点

标签 java swing jtextfield joptionpane

我正在尝试显示一个带有 JTextFieldJOptionPane,它具有初始焦点,一旦用户按下 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”按钮。

我试过监听器,但似乎我无法从其中访问非最终数据(即文本字段)。

最佳答案

基本上,您有几个问题正在相互解决 :-)

  • 初始聚焦组件:使用 createOptionDialog 方法在消息字段中传入多个自定义组件,并将初始组件作为“initialSelectionValue”传递,这有点小技巧。
  • 自定义按钮:再次将自定义文本(或真正的按钮,并不重要)作为选项参数传递是一个小技巧。实际上,它意味着用户可以选择,其中之一是最初选择的(然后获得焦点)
  • 对文本字段第一个按钮的操作(==封闭根 Pane 中的默认按钮):此处字段本身阻碍了这两个操作,因为它吃回车键

最后一个可以通过 JTextField 的自定义子类来解决,就像 BasicOptionPaneUI 用于 inputDialog 一样,它显示在最后 - 仅当前两个被解决时才在 optionPane 上下文中有用。我还没有看到一个完全令人满意的解决方案:将“消息”的概念与“选项”的概念混合会使 optionPane 混淆为 not 设置 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);

关于java - JOptionPane 元素之间的交替焦点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7666309/

相关文章:

Java Applet Web部署问题

Java HitTest 行为异常

java - 在 jTextfield 中禁用 'paste'

java - JTextfield 应触发所有键盘输入

java - 未发送订阅者的 Firebase 指数退避

java - 从 RGB 数据的 int 数组创建 PNG 文件

Java 8 - 在 CompleteableFuture 的 thenCompose 方法中处理元素列表

java while循环 try catch ,无法打印到新行

java - 在Java中使用什么方法键盘按键来移动东西而不是ActionListener

java - 帮助编写您自己的 javax.swing.text.Document