当我来自KeyListener时,我很困惑为什么JTextField似乎没有通过使用setText(“”)方法来“清除”。它可以在ActionListener中正常工作,但最令人惊讶的是,如果KeyListener方法尝试使用虚拟动作事件(动态创建为简单测试)来调用ActionListener方法,它仍会保留已键入的文本。 / p>
换句话说,当你从命令行运行它时,如果你在字段中键入一个“3”,你会看到setText(“test”)方法不会消除3,如我会期待和渴望,而是将它留在原地。然后,您将在显示屏中看到“test3”。我注意到这一行有评论。单击JButton将正确删除文本。 JButton和JLabel将正确地更改文本。但JTextField不会。如果然后按下按钮,您将看到action事件正确清除了JTextField。现在,如果您切换注释掉的行,您可以看到尝试从KeyTyped方法调用actionPerformed方法!而且,当您在文本字段中键入“3”时,它将不会被删除。我希望setText(“”)方法清除它,它不会。即使keyTyped()方法正在调用与JTextButton相同的actionPerformed()方法,这也是如此。
这里的动机可能会有所帮助。我需要捕获一个特定的热键,它会在键入时清除JTextField,就像按下“清除”按钮一样。这似乎不起作用。
我以前没有用Swing做过那么多,但这很令人费解。
我的SSCCE代码如下:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
class P2 implements KeyListener, ActionListener
{
JTextField fld;
JButton btn;
JLabel lbl;
P2()
{
JFrame frm = new JFrame("Test");
fld = new JTextField(10);
JPanel pnl = new JPanel();
btn = new JButton("Clear it out");
lbl = new JLabel("This is a test");
fld.addKeyListener(this);
btn.addActionListener(this);
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frm.setSize(400,400);
frm.setLayout(new FlowLayout() );
pnl.add(fld);
pnl.add(btn);
pnl.add(lbl);
frm.getContentPane().add(pnl);
frm.setVisible(true);
}
public void keyPressed(KeyEvent ke) {}
public void keyReleased(KeyEvent ke) {}
public void keyTyped(KeyEvent ke)
{
System.out.println("got a pressed key");
//this is the setText method that ought to wipe clean the field comments:
this.fld.setText("test");
this.btn.setText("try again");
this.lbl.setText("got a presseed key");
//toggle this comment to see the invocation of the action event:
// this.actionPerformed(new ActionEvent( new Object(), 2, "test") );
}
public void actionPerformed(ActionEvent ae)
{
fld.setText("");
fld.selectAll();
}
public static void main(String[] args)
{
SwingUtilities.invokeLater
(
new Runnable()
{
public void run()
{
new P2();
}
}
);
}
}
答案 0 :(得分:2)
此行为是由于KeyEvent
被解雇后字段将处理KeyListener
这一事实。您可以通过
ke.consume();
在方法keyTyped
内。
根据您的要求,另一种方法是将清算调用封装在SwingUtilities.invokeLater
内,这将在您当前事件之后处理,从而在更新后清除该字段。
答案 1 :(得分:2)
这是一个代码片段,使用键绑定来消除所有按下'a'的文本,实现使用已经在字段的动作映射中注册的动作(注意你仍然需要将代码包装到SwingUtilities.invokeLater中 - 因为霍华德已经建议 - 保证在字段内部处理后处理
JTextField normal = new JTextField("just a normal field", 10);
final Action selectAll = normal.getActionMap().get("select-all");
final Action cut = normal.getActionMap().get("cut-to-clipboard");
Action combine = new AbstractAction() {
@Override
public void actionPerformed(final ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
selectAll.actionPerformed(e);
cut.actionPerformed(e);
}
});
}
};
normal.getActionMap().put("magic-delete-all", combine);
normal.getInputMap().put(KeyStroke.getKeyStroke("A"), "magic-delete-all");