当 KeyEvent.VK_ENTER 重新分配给它时,如何让 JTextField 触发它的 ActionEvent? [英] How can I make a JTextField fire it's ActionEvent when KeyEvent.VK_ENTER is redispatched to it?

查看:21
本文介绍了当 KeyEvent.VK_ENTER 重新分配给它时,如何让 JTextField 触发它的 ActionEvent?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 KeyboardFocusManager 和我自己的自定义 KeyEventDispatcher,它将所有 KeyEvent 重新分配到一个特定的 JTextField,无论 JFrame 内的焦点如何.就文本输入而言,这就像一个魅力,但我也希望 JTextFieldKeyEvent.VK_ENTER 将其文本发布到 JTextArea> 重新分配给它.出于某种原因,它不会这样做.我在 JTextField 上设置了一个 actionListener,如果我在文本字段中有光标并按 ENTER,它将被触发,但是如果 ENTER 事件来自 KeyboardFocusManager,它不会被触发.redispatchEvent(keyEvent).

I am playing around with the KeyboardFocusManager and my own custom KeyEventDispatcher that redispathes all KeyEvents to one particular JTextField, regardless of focus within the JFrame. This works like a charm as far as textual input is concerned but I also want the JTextField to post its text to a JTextArea when a KeyEvent.VK_ENTER is redispatched to it. For some reason it just won't do this. I've set an actionListener on the JTextField which will be fired on if I have the cursor in the text field and press ENTER, however it's not fired on if the ENTER event comes from a KeyboardFocusManager.redispatchEvent(keyEvent).

我还尝试在按下 ENTER 的情况下重新分配 ActionEvent 而不是未更改的 KeyEvent,但无济于事:( 您可能认为将 ActionEvent 分配给组件会触发它的 ActionListeners 但不会.

I've also tried redispathing an ActionEvent rather than the unchanged KeyEvent in the case ENTER is pressed, but to no avail :( You would think that dispathing an ActionEvent to a component would fire it's ActionListeners but nope.

谁能解释一下这是为什么?也许提出一个巧妙的方法来解决它?

Can someone explain why this is? And maybe propose a neat way around it?

SSCCE:

package viewlayer.guiutil.focus;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.Runnable;import java.lang.String;
import java.util.Date;

public class Test extends JFrame
{
    private JTextField m_chatInput;
    private JTextArea m_textArea;

    public static void main(String... args)
    {
        Test test1 = new Test();
        test1.run(test1);
    }

    public void run(final Test test)
    {
        test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        test.setSize(250, 400);

        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new MyKeyEventDispatcher());

        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                test.init();
            }
        });

        test.setVisible(true);
    }

    public void init()
    {
        JPanel panel = new JPanel (new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(2,5,1,1);
        gbc.weightx = 1.0;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.gridwidth = GridBagConstraints.REMAINDER;

        JLabel chatLabel = new JLabel("Chat input field:");
        panel.add(chatLabel,gbc);

        m_chatInput = new JTextField(15);
        m_chatInput.setActionCommand(MyActionListener.ACTION_PERFORMED);
        m_chatInput.addActionListener(new MyActionListener());
        panel.add(m_chatInput,gbc);

        JTextField chatInput = new JTextField(15);
        panel.add(chatInput,gbc);

        JLabel text = new JLabel("chat history:");
        panel.add(text,gbc);

        m_textArea = new JTextArea(5, 15);
        m_textArea.setFocusable(false);
        panel.add(m_textArea,gbc);

        JButton postButton = new JButton("Post");
        postButton.setActionCommand(MyActionListener.ACTION_PERFORMED);
        postButton.addActionListener(new MyActionListener());
        panel.add(postButton,gbc);
        gbc.weighty = 1.0;
        gbc.anchor = gbc.NORTHWEST;

        setLayout(new FlowLayout(FlowLayout.LEFT));
        add(panel);
    }

    private class MyKeyEventDispatcher implements KeyEventDispatcher
    {
        public boolean dispatchKeyEvent(KeyEvent keyEvent)
        {
            KeyboardFocusManager.getCurrentKeyboardFocusManager().redispatchEvent(m_chatInput, keyEvent);

            return false;
        }
    }

    private class MyActionListener implements ActionListener
    {
        private static final String ACTION_PERFORMED = "ACTION_PERFORMED";

        public void actionPerformed(ActionEvent actionEvent)
        {
            if(actionEvent.getActionCommand().equals(ACTION_PERFORMED))
            {
                Date date = new Date(System.currentTimeMillis());
                m_textArea.append(date.getHours() +":"+ date.getMinutes() +":"+ date.getSeconds() + " - " + m_chatInput.getText() + "\n");
                m_chatInput.setText("");
            }
        }
    }
}

推荐答案

文本字段代码有一个测试,以确保在调用侦听器代码之前组件有焦点:

The text field code has a test to make sure the component has focus before invoking the listener code:

    public void actionPerformed(ActionEvent e) {
        JTextComponent target = getFocusedComponent();
        if (target instanceof JTextField) {
            JTextField field = (JTextField) target;
            field.postActionEvent();
        }
    }

但是,您应该能够直接从 KeyEventDispatcher 调用 postActionEvent() 方法:

However, you should be able to invoke the postActionEvent() method directly from your KeyEventDispatcher:

if (enter key)
   m_chatInput.postActonEvent();
else
   // redispatch the event

这篇关于当 KeyEvent.VK_ENTER 重新分配给它时,如何让 JTextField 触发它的 ActionEvent?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆