2

我正在玩弄KeyboardFocusManager我自己的习惯,不管 JFrame 中的焦点如何,都将KeyEventDispatcher所有KeyEvents 重新移到一个特定的 s 上。JTextField就文本输入而言,这就像一种魅力,但我也希望在将 a 重新分派给 a时将JTextField其文本发布到 a 。出于某种原因,它只是不会这样做。如果我将光标放在文本字段中并按 ENTER,我已经在 上设置了一个 actionListener ,但是如果 ENTER 事件来自.JTextAreaKeyEvent.VK_ENTERJTextFieldKeyboardFocusManager.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("");
            }
        }
    }
}
4

3 回答 3

3

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

    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
于 2011-02-22T17:02:45.140 回答
0

您应该删除此行:

m_chatInput.setFocusable(false);

在这条线上:

Date date = new Date(System.currentTimeMillis());

你应该插入:

requestFocusInWindow(m_chatInput);

如果这对您有用,或者我们需要进行更多调整,请发布。

于 2011-02-22T13:46:32.447 回答
0

我想我找到了一种解决方法,您可以使用它来将注意力集中在 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);
            }
        }
    }
 );

我根据在以下位置找到的一些代码对其进行了修改:

http://download.oracle.com/javase/tutorial/uiswing/misc/focus.html

于 2011-02-22T14:40:25.700 回答