当KeyEvent.VK_ENTER被重新分配到它时,如何让JTextField触发它的ActionEvent?

时间:2011-02-22 13:19:01

标签: java swing keyboardfocusmanager

我正在使用KeyboardFocusManager和我自己的自定义KeyEventDispatcher,无论JFrame中的焦点如何,都会将所有KeyEvent重新分配给一个特定的JTextField。就文本输入而言,这就像魅力一样,但我还希望JTextField在将JTextArea重新发送到KeyEvent.VK_ENTER时将其文本发布到JTextField。出于某种原因,它不会这样做。我在KeyboardFocusManager.redispatchEvent(keyEvent)上设置了一个actionListener,如果我将光标放在文本字段中并按下ENTER,将触发该操作,但是如果ENTER事件来自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(""); } } } } ,则不会触发它。 / p>

我也尝试重新路由一个ActionEvent而不是在按下ENTER的情况下未更改的KeyEvent,但无济于事:(你会认为将一个ActionEvent调度到一个组件会触发它的ActionListeners但是没有。

有人可以解释为什么会这样吗?也许可以提出一个巧妙的方法吗?

SSCCE:

{{1}}

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

你应该删除这一行:

m_chatInput.setFocusable(false);

在线上方:

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

你应该插入:

requestFocusInWindow(m_chatInput);

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

答案 2 :(得分: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