关于java:JTextField将不接受输入

JTextField Won't accept Input

因此我制作了一个带有JTextField的测试窗口。而且我不知道出了什么问题。主要代码在下面。问题是,无论我做什么,我都无法编辑文本字段,也无法编辑创建的第二个字段。我有一个示例程序,该程序的文本字段也能正常工作,但根本无法正常工作。

我不确定是否需要发布它,但是我可以在此处获取完整程序的示例jar。我只发布了处理文本Fields

的区域

编辑:完整的源代码在这里:GITHUB

我删除了一些东西,它起作用了,我放弃了... \\\\

EDIT2:事实证明,这是我在调用扩展了JPanel的类的事实,只是调用一个新的JPanel而不是扩展它的工作原理

EDIT3:好的,问题出在关键事件分配器上,我标记为答案的帖子对其进行了深入的解释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 public class Main {
    private static JPanel mainPanel = new JPanel();
    private static JFrame frame;
    public static JTextField textField1 = new JTextField();
    public static JTextField textField2 = new JTextField();
    private static GroupLayout layout = new GroupLayout(mainPanel);

    public static void main(String[] Args) throws InterruptedException{
        frame = new JFrame("Test Window");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainPanel.setLayout(layout);
        layout.setAutoCreateContainerGaps(false);
        layout.setAutoCreateGaps(false);
        GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
        GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
        vGroup.addGap(200).addGroup(layout.createParallelGroup().addComponent(textField1, 25, 25, 25).addComponent(textField2, 25, 25, 25).addGap(350));
        hGroup.addGap(300)
        .addGroup(layout.createParallelGroup().addComponent(textField1, 200, 200, 200).
                addComponent(textField2, 200, 200, 200)).addGap(300);
        layout.setVerticalGroup(vGroup);
        layout.setHorizontalGroup(hGroup);
        frame.add(mainPanel);
        frame.pack();
        frame.setResizable(false);
        frame.setVisible(true);
        textField1.setText("I am a simple uneditable testbox");
    }
}


您的问题是我怀疑KeyEventDispatcher。当您将其重新添加并返回true时,JTextField将不起作用。根据KeyEventDispatcher API:

If an implementation of this method returns false, then the KeyEvent is passed to the next KeyEventDispatcher in the chain, ending with the current KeyboardFocusManager. If an implementation returns true, the KeyEvent is assumed to have been dispatched (although this need not be the case), and the current KeyboardFocusManager will take no further action with regard to the KeyEvent.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;

import javax.swing.*;

public class Main {
   private static JPanel mainPanel = new JPanel();
   private static JFrame frame;
   public static JTextField textField1 = new JTextField(20);
   public static JTextField textField2 = new JTextField(20);

   public static void main(String[] Args) throws InterruptedException {
      frame = new JFrame("Test Window");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

      final JCheckBox dispatchKeyEventReturnCheckBox =
            new JCheckBox("Dispatch Key Event Return Value", true);

      mainPanel.add(textField1);
      mainPanel.add(textField2);
      mainPanel.add(dispatchKeyEventReturnCheckBox);
      frame.add(mainPanel);

      KeyboardFocusManager.getCurrentKeyboardFocusManager()
            .addKeyEventDispatcher(new KeyEventDispatcher() {

               @Override
               public boolean dispatchKeyEvent(KeyEvent evt) {
                  // TODO Fix this!!!
                  // !! return false;
                  return dispatchKeyEventReturnCheckBox.isSelected();
               }
            });

      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
      textField1.setText("I am a simple uneditable testbox");
   }
}

解决方案:1)除非您不希望GUI处理按键,否则不要让dispatchKeyEvent(KeyEvent e)返回true。或2)甚至更好,不要使用此类。而是告诉我们您为什么觉得自己需要它,让我们帮助您找到更好的方法。

1,用于尝试创建和发布MCVE。


请勿使用有时会挂起整个swing应用程序的Thread.sleep(),而是尝试最适合swing应用程序的Swing Timer。

了解更多如何使用Swing计时器

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
private Timer timer;
...

// wait for 10 milli-seconds
timer = new javax.swing.Timer(10, new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent arg0) {
        // next call
    }
});
timer.setRepeats(true); // you can turn off reputation
timer.start();