如何在 Java 中找到焦点中的 JTextField?

How to find the JTextField in focus in Java?

在我的 Java Swing 应用程序中,我有多个用于日期的 JTextField,单击时有一个 JButton,它将打开一个日历以选择一个日期,日期字符串应插入其中一个JTextFields,所以我想设计程序,以便用户首先单击他想要输入日期的日期 JTextField [关注该字段并记住它],程序将 JTextField 保存为目标组件,然后将该组件传递给用于输入所选日期的日历对象。到目前为止,我可以对程序进行硬编码,以便它可以将我选择的任何日期字符串输入到我已经硬编码的某个 JTextField 中,但问题是如何记住 JTextField 用户单击的?所以我不必硬编码。

我试过了:Date_Field.getDocument().addDocumentListener(A_Listener); 在用户开始输入之前,它不会获得焦点。

我也试过了:

Date_Field.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent evt) {
     Focused_Date_TextField=(JTextField)evt.getSource();
  }
});

也没有用,因为当用户点击它时,在用户开始输入之前还没有任何动作[因此没有焦点]。

那么,当用户不输入任何内容而只需单击它时,有什么方法可以获取 JTextField?

JTextFieldJButton 合并到自定义组件(可能是 JPanel)中并隔离其中的功能。这样,该按钮始终与给定的 JTextField 相关联,您不关心哪个字段是 "focused" 最后一个

public class DateField extends JPanel {
    private JTextField field;
    private JButton btn;

    public DateField() {
        setLayout(new FlowLayout(FlowLayout.LEFT));

        field = new JTextField(11);
        btn = new JButton("...");

        add(field);
        add(btn);

        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // Show calendar, get date do all that funky stuff
                field.setText(dateAsString);
            }
        });
    }

}

然后您可以根据需要创建任意数量的这些,并将它们添加到您想要的任何容器中

MadProgrammer 的建议是您解决问题的方式。这是您将在其他应用程序中看到的常见 UI。

How to find the JTextField in focus in Java?

然而,为了在处理文本组件时回答您上面的更一般的问题,您可以创建一个从 TextAction 扩展的 ActionTextAction 有一个 getFocusedComponent() 方法,它 return 是最后一个具有焦点的文本组件。

例如:

public class SelectAll extends TextAction
{
    public SelectAll()
    {
        super("Select All");
    }

    public void actionPerformed(ActionEvent e)
    {
        JTextComponent component = getFocusedComponent();
        component.selectAll();
        component.requestFocusInWindow();
    }
}

因此,通常您会使用此 class 创建 JMenuItem,然后将菜单项添加到 JMenuBar 上的 JMenu。这实际上就是 JDK 的 cut/copy/paste 操作的工作方式。

同样,我不推荐将其作为此问题的解决方案,但当您希望在多个文本组件之间共享一个 Action 时,可以解决未来的问题。

此外,当您使用此方法时,getFocusedComponent() 方法将 return 任何文本组件,因此您不能保证最后一个获得焦点的组件是您的日期字段之一。不使用这种方法的另一个原因。

感谢您的回答和建议,但它们不是我想要的。太麻烦了,我的应用程序中没有足够的 space 来向每个字段添加按钮,即使我确实有足够的 space,它们看起来太忙了,无法容纳数十个字段,每个字段都有自己的按钮,我想清理简单的外观,但仍按我喜欢的方式运行,所以我进行了一些搜索并找到了理想的答案,这是实现它的方法:

Date_TextField[Index].addFocusListener(new FocusListener()
{
  public void focusGained(FocusEvent e)
  {
    Out("Focus gained : "+e.toString());
    Focused_Date_TextField=(JTextField)e.getSource();
  }

  public void focusLost(FocusEvent e)
  {
    Out("Focus lost : "+e.toString());
  }
}); 

I then pass Focused_Date_TextField to the calendar, so when a date is picked, the date text will be input into the user selected JTextField.