JTextField が KeyListener からのものであるのに、setText("") メソッドを使用しても JTextField が単に「クリア」されないように見えるのはなぜでしょうか。これは ActionListener から正常に動作しますが、最も驚くべきことに、KeyListener メソッドがダミーのアクション イベント (単純なテストとしてその場で作成) を使用して ActionListener メソッドを呼び出そうとすると、入力されたテキストはそのまま残ります。
つまり、コマンド ラインから実行するときに、たとえばフィールドに「3」と入力すると、予想どおり、setText("test") メソッドが 3 を消去しないことがわかります。と欲望しますが、むしろそれをそのままにしておきます。ディスプレイに「test3」が表示されます。この行にコメントを付けました。JButton をクリックすると、テキストが適切に消去されます。JButton と JLabel はテキストを適切に変更します。しかし、JTextField はそうしません。次にボタンを押すと、アクション イベントが 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();
}
}
);
}
}