Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何让JTextField启动它';当KeyEvent.VK_ENTER被重新修补到它时,它的ActionEvent?_Java_Swing_Keyboardfocusmanager - Fatal编程技术网

Java 如何让JTextField启动它';当KeyEvent.VK_ENTER被重新修补到它时,它的ActionEvent?

Java 如何让JTextField启动它';当KeyEvent.VK_ENTER被重新修补到它时,它的ActionEvent?,java,swing,keyboardfocusmanager,Java,Swing,Keyboardfocusmanager,我正在玩KeyboardFocusManager和我自己定制的KeyEventDispatcher,它将所有KeyEvents重新路由到一个特定的JTextField,而不考虑JFrame中的焦点。就文本输入而言,这就像一个符咒,但我也希望JTextField在KeyEvent.VK_ENTER被重新修补时将其文本发布到JTextArea。出于某种原因,它不会这样做。我在JTextField上设置了一个actionListener,如果光标在文本字段中并按ENTER键,它将被激活,但是如果ENT

我正在玩
KeyboardFocusManager
和我自己定制的
KeyEventDispatcher
,它将所有
KeyEvent
s重新路由到一个特定的
JTextField
,而不考虑JFrame中的焦点。就文本输入而言,这就像一个符咒,但我也希望
JTextField
KeyEvent.VK_ENTER
被重新修补时将其文本发布到
JTextArea
。出于某种原因,它不会这样做。我在
JTextField
上设置了一个actionListener,如果光标在文本字段中并按ENTER键,它将被激活,但是如果ENTER事件来自
KeyboardFocusManager.redispatchEvent(keyEvent)
,它不会被激活

我还尝试过在按下ENTER键的情况下重新路由ActionEvent,而不是不变的KeyEvent,但没有结果:(您可能认为将ActionEvent分派给组件会触发它的ActionListeners,但没有

有人能解释一下为什么会这样吗?也许能提出一个巧妙的解决办法

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("");
            }
        }
    }
}

您应该删除此行:

m_chatInput.setFocusable(false);
线以上:

Date date = new Date(System.currentTimeMillis());
你应插入:

requestFocusInWindow(m_chatInput);

如果这对你有用,或者我们需要做更多的调整,请发布。

我想我找到了一个可以让你专注于聊天输入的工作:

requestFocusInWindow(m_chatInput);
KeyboardFocusManager focusManager =
KeyboardFocusManager.getCurrentKeyboardFocusManager();
focusManager.addPropertyChangeListener(
    new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent e) {
            String prop = e.getPropertyName();
            if ("focusOwner".equals(prop)) {
            requestFocusInWindow(m_chatInput);
            }
        }
    }
 );
我根据在以下位置找到的一些代码对其进行了修改:


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

    public void actionPerformed(ActionEvent e) {
        JTextComponent target = getFocusedComponent();
        if (target instanceof JTextField) {
            JTextField field = (JTextField) target;
            field.postActionEvent();
        }
    }
但是,您应该能够直接从KeyEventDispatcher调用postActionEvent()方法:

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

当你点击“Post”按钮时它能工作吗?设置聚焦(假)只是为了进一步优化我想做的事情,它是否可聚焦并不重要,因为我不想将焦点设置回我的m_chatInput。我想解决的实际问题是,即使由于应用程序中的其他事件而失去焦点,也要将输入定向到聊天室。这是为了避免手动设置将注意力放回聊天室(通过鼠标点击),以便能够完成文字的编写和发送。也许应该把这个问题放在原始问题中:)另外,到目前为止,我甚至不会使用actionPerformed方法,除非焦点已经放在m_chatInput上。是的,我理解这一点。您正在尝试{如果不在焦点->重定向,如果在焦点->重定向},而我正在尝试{如果不在焦点->重定向,如果在焦点->快乐之路}是的,如果m_chatInput已经具有焦点,您的自定义键盘FocusManager将不会被触发,因此只需在m_chatInput中安装另一个操作侦听器。我已使用另一个JTexField更新SSCE,并使此和m_chatInput都具有焦点。现在您可以看到,无论哪个文本字段具有焦点/光标,文本总是添加到m_chatInput。但是,只有当m_chatInput具有焦点时,按ENTER键发送才会起作用。。。奇怪,谢谢你的努力。然而,这不是焦点的问题,事实上,这甚至是一个要求,我不让聊天保留或窃取焦点回来。我看到我之前的评论“这是为了避免手动将焦点设置回聊天(通过鼠标点击)以便能够完成写作和发送文本”会让你感到困惑,这是第二部分很重要,要让用户完成他正在写的内容并使用ENTER发送,即使聊天时注意力不集中。我认为我最初的问题的答案是您不能(除非您扩展JTextField或其他内容)。你的解决方案对SSCCE有效,所以我给你一个接受的机会。非常感谢。