【问题标题】:Getting ENTER to work with a JSpinner the way it does with a JTextField让 ENTER 像使用 JTextField 一样使用 JSpinner
【发布时间】:2008-12-18 23:19:36
【问题描述】:

首先,为了让我的工作更容易解释,这是我的一些代码:

JSpinner spin = new JSpinner();
JFormattedTextField text = getTextField(spin);

text.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent evt) {
            // Do stuff...
    }
});

...

private JFormattedTextField getTextField(JSpinner spinner) {
    JComponent editor = spinner.getEditor();

    if (editor instanceof JSpinner.DefaultEditor) {
        return ((JSpinner.DefaultEditor )editor).getTextField();
    } else {
        System.err.println( "Unexpected editor type: "
                           + spinner.getEditor().getClass()
                           + " isn't a descendant of DefaultEditor" );
        return null;
    }
}

如您所见,我已经做到了。事实上,当我在微调器的文本字段组件中输入一个值 (JFormattedTextField),然后按 ENTER,它就可以工作了。

我现在想要的是能够让文本字段响应 ENTER 而无需手动输入新值(这有点违背了制作微调器的目的)。我该怎么做?

【问题讨论】:

    标签: java swing jtextfield listeners jspinner


    【解决方案1】:

    我知道这不是动作监听器……但也许这对你有用?

    
        text.addKeyListener( new KeyAdapter() {
                @Override
                public void keyReleased( final KeyEvent e ) {
                    if ( e.getKeyCode() == KeyEvent.VK_ENTER ) {
                        System.out.println( "enter pressed" );
                    }
                }
            } );
    

    【讨论】:

    • 乐于助人。虽然我想知道为什么动作监听器不起作用:D
    • 击败我。 :P 可能是因为 JSpinner 以某种方式窃取了输入?
    • 我可能会使用 getInputMap() 和 getActionMap(),但感谢您的帖子!
    【解决方案2】:

    我自己也遇到了一个与此相关的问题。就我而言,我有一个带有SpinnerNumberModel 设置的JSpinner,因此我可以输入数字ID 值,然后从远程数据库中检索它们。使用 JButton 作为我的查询触发器,这一切都很好,但我希望能够通过 Tab 将焦点切换到该字段,然后按 Enter,并且还能够通过输入带有数字键的 ID 来更改值,然后按回车键。

    给我最多的问题是使用数字键手动输入 ID,然后按 Enter。当我这样做时,查询仍然会发生,但它正在查询以前的 ID 而不是我刚刚输入的 ID,所以我必须再次按 Enter 来查询新的 ID(见代码)

    ((JSpinner.DefaultEditor) minRng.getEditor()).getTextField().addKeyListener(new KeyAdapter() {
        @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                queryData();
            }
        }
    });
    

    及查询方法:

    private void queryData() {
        int minVal = Integer.parseInt(minRng.getValue().toString());
        queryDataBase(minVal);
    }
    

    为了解决这个问题,我所要做的就是强制查询等待运行,直到微调器更新其值,这很容易通过使用 SwingUtilities.invokeLater() 将其强制到 EDT 队列的末尾来完成,例如所以:

    ((JSpinner.DefaultEditor) minRng.getEditor()).getTextField().addKeyListener(new KeyAdapter() {
        @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        queryData();
                    }
                });
            }
        }
    });
    

    感谢invokeLater(),当按下回车键时,查询现在发生在新值而不是前一个值上,因为 JSpinner 已将其值更新为新输入的值。

    我假设这样做的原因是输入的值没有正式应用于JSpinner,直到您按回车键,这也会触发查询的键侦听器。自定义 [query] 键侦听器的 KeyEvent 似乎是队列中的第一个,因此它首先运行其代码,然后是 KeyEvent 用于将值从内部 JFormattedTextField 应用到 JSpinner ,这就是它查询旧值的原因。 SwingUtilities.invokeLater() 只是将查询本身放在队列的末尾,因此它允许另一个 KeyEvent 在运行查询之前完成其代码。

    编辑:

    实现此目的的另一种方法是直接从JFormattedTextField 而不是JSpinner 请求值,因为这也应该返回新输入的值,因为JFormattedTextField 包含您输入的值,但它没有' 尚未传递给 JSpinner,这似乎是问题所在。

    private void queryData() {
        JFormattedTextField tf = ((JSpinner.DefaultEditor) minRng.getEditor()).getTextField();
        int minVal = Integer.parseInt(tf.getText());
        queryDataBase(minVal);
    }
    

    此方法的唯一问题是您必须在解析值时捕获任何NumberFormatExceptions,其中SwingUtilities.invokeLater() 方法允许微调器模型自动删除任何无效字符并继续查询.

    无论如何,我对Java还是有些陌生,所以如果我对此的理解有误,请在cmets中告诉我。

    【讨论】:

      【解决方案3】:

      我认为您要问的是,当我们手动编辑 JSpinner 显示的值时,它实际上并没有改变它,而只是显示为它。

      原因是 JSpinner 使用了一个叫做编辑器的东西并且有一个值。编辑器负责显示当前值并更改它(但只能使用箭头按钮)

      如果我们想自己编辑,那么我们需要使用

      spinner.commitEdit();
      

      看看这个以获得更多知识,

      https://docs.oracle.com/javase/7/docs/api/javax/swing/JSpinner.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-13
        • 1970-01-01
        • 2014-07-02
        • 1970-01-01
        • 1970-01-01
        • 2013-11-03
        • 2019-07-30
        • 1970-01-01
        相关资源
        最近更新 更多