【问题标题】:Java KeyListener not firing on JSpinnerJava KeyListener 没有在 JSpinner 上触发
【发布时间】:2010-10-06 15:00:00
【问题描述】:

已经尝试了几种不同的方法,但到目前为止都没有成功。只是想知道我是否遗漏了什么。我有一个 JSpinner,它是日历旁边的 DateSelector 小部件的一个组件。如果用户更改 JSpinner 中的任何文本而不是使用 Calendar 控件或 JSpinner 上下箭头,我将尝试触发验证方法。

以下是我尝试过的不同方法:

jSpinner1.addKeyListener(kl);

jSpinner1.getEditor().addKeyListener(kl);

((JSpinner.DefaultEditor) jSpinner1.getEditor().getTextField().addKeyListener(kl);

有人知道我做错了什么吗?谢谢

更新 抱歉,我应该说我已经将 ChangeListener 添加到附加到 JSpinner 的 JSpinnerDateModel 中。像这样:

ChangeListener changeListener = new ChangeListener() {
        @Override
        public void stateChanged(ChangeEvent e) {
            dateChanged();
        }
    };

    jSpinnerDateModel.addChangeListener(changeListener);

    KeyListener keyListener = new KeyListener() {

        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void keyPressed(KeyEvent e) {
            System.out.println(e.getKeyChar());
            dateChanged();
        }

        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub

        }

    };
    ((JSpinner.DefaultEditor) jSpinner1.getEditor()).getTextField().addKeyListener(
            keyListener);

谢谢

弗兰克

【问题讨论】:

    标签: java swing listener keylistener jspinner


    【解决方案1】:

    如果您想禁用键盘编辑,请执行以下操作:

    JFormattedTextField tf = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField();
    tf.setEditable(false);
    

    要侦听关键事件,您需要向文本字段添加侦听器。这对我有用:

    ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField().addKeyListener(new KeyListener(){
    
                @Override
                public void keyPressed(KeyEvent e) {                    
                }
    
                @Override
                public void keyReleased(KeyEvent e) {
                    System.out.println("PRESSED!");                    
                }
    
                @Override
                public void keyTyped(KeyEvent e) {                    
                }
    
            });
    

    【讨论】:

    • 是的,谢谢。如果必须,我将其作为最后一个选项,但我希望用户拥有使用控件或通过键盘手动编辑日期的完全访问权限。
    • 谢谢,但我已经有了这个代码 - 我已经更新了问题以显示所有正在使用的代码。对此感到抱歉。
    【解决方案2】:

    JSpinners 自己处理 KeyEvents,但他们将 ChangeEvents 发送到外部世界。添加一个 ChangeListener 应该允许您执行您希望的验证。

    另请参阅:Detecting Spinner Value Changes (Java Tutorials)

    【讨论】:

    • 很抱歉未在原始问题中包含此信息(我现在已更新),但我已经将 ChangeListener 附加到 JSpinner 的模型中。这会捕获对 JSpinner 中的值所做的任何更改,但前提是用户使用 JSpinner 控件。当用户通过键盘手动编辑 JSpinner 的值时,我试图触发 KeyListener 的按键事件。谢谢
    • @Frank:每当用户更改值并聚焦(或按 Enter)时,都会触发 ChangeListener。不过,您是对的,它不会在用户输入时触发。
    • 是的,这就是我遇到的问题。这是向导面板的一部分,如果用户只是选择一个日期并单击下一步,那么焦点不会丢失并且验证方法触发得太晚。无论如何,感谢您的输入。似乎比最初想象的要棘手。
    • @Frank:我刚刚尝试了您发布的 KeyListener 代码,我看到每次更改微调器的文本时都会打印出事件。你什么也得不到吗?
    • 真的吗?我的 ChangeListener 很好,但如果我专注于 JSpinner 的 Textfield 并手动编辑值,我什么也得不到。我已经为所有关键事件设置了断点,但它没有触发它们。没有输出。如何使用相同的代码获得成功?它一定是别的东西......只有当你的作品有效时它才有意义。谢谢,我会继续尝试不同的东西。
    【解决方案3】:

    这是 Swing 的不足,我认为 JSpinner 应该遵循 JComboBox 提供对底层文本字段的以下访问权限:

    JComboBox.getEditor().getEditorComponent()
    

    通过查看 J1.7 的源代码,我发现您可以通过以下方式实现几乎相同的目标

    JSpinner.getEditor().getComponent(0)
    

    因此,您可以通过以下方式“破解”侦听器:

    JSpinner.getEditor().getComponent(0).addKeyListener(...)
    

    显然,这取决于 swing 的“幕后”实现,并在 J1.7 中工作,但不能保证这适用于未来或过去的其他版本。

    享受吧。

    编辑

    或者如果编辑器是 DefaultEditor 的一个实例,您可以将其转换为这样并使用“getTextField()”。如果在接口中定义了这将很方便。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-19
      • 2013-06-04
      • 1970-01-01
      • 2011-07-09
      • 1970-01-01
      • 2014-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多