当 KeyEvent.VK_ENTER 重新分配给它时,如何让 JTextField 触发它的 ActionEvent? [英] How can I make a JTextField fire it's ActionEvent when KeyEvent.VK_ENTER is redispatched to it?
问题描述
我正在使用 KeyboardFocusManager
和我自己的自定义 KeyEventDispatcher
,它将所有 KeyEvent
重新分配到一个特定的 JTextField
,无论 JFrame 内的焦点如何.就文本输入而言,这就像一个魅力,但我也希望 JTextField
在 KeyEvent.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 KeyEvent
s 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屋!