【问题标题】:How to find the JTextField in focus in Java?如何在 Java 中找到焦点所在的 JTextField?
【发布时间】:2016-07-26 04:19:51
【问题描述】:

在我的 Java Swing 应用程序中,我有多个用于日期的 JTextField,单击时有一个 JButton,它将打开一个日历来选择一个日期,并且日期字符串应该插入到其中一个 JTextField 中,所以我想设计程序,让用户首先点击一个日期 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 呢?

【问题讨论】:

  • 变量名不应以大写字符开头。

标签: java swing focus jtextfield


【解决方案1】:

JTextFieldJButton 组合成一个自定义组件(可能是JPanel)并隔离其中的功能。这样,按钮总是与给定的JTextField 相关联,您不必关心最后“聚焦”哪个字段

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);
            }
        });
    }

}

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

【讨论】:

  • (1+) 这个特定问题的更好解决方案。
【解决方案2】:

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

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

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

例如:

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

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

因此,通常您会使用此类创建JMenuItem,然后将菜单项添加到JMenuBar 上的JMenu。这实际上是 JDK 的剪切/复制/粘贴操作的工作原理。

同样,我不建议将其作为解决此问题的方法,但对于将来要在多个文本组件之间共享 Action 时出现的问题。

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

【讨论】:

    【解决方案3】:

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

    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());
      }
    }); 
    

    我然后将聚焦ocused_date_textfield传递给日历,因此在挑选日期时,将在用户选择的jtextfield中输入日期文本。

    【讨论】:

    • 因为用户不会混淆“任何”文本字段都可以通过一个按钮来控制......是的,这很直观
    • they look too busy for dozens of fields - 也许你应该从清理 UI 的那部分开始。这里有些东西非常奇怪。为什么一个表单会有几十个日期字段?
    • @camickr : 假设我的应用程序有多个学员注册培训课程的条目,每个学员都有开始日期和结束日期,每个人可以选择不同的日期,并且在表格有 30 个或更多条目......每个日期字段我只有足够的长度输入:2016-04-06 [没有更多额外的空间用于另一个按钮。 ] 请参阅已编辑的问题以获取屏幕截图。
    • 我们只是建议大多数用户不熟悉这种类型的 UI。此外,对表单上的多个条目进行硬编码通常不是一个好的设计。也许相反,数据存储在 JTable 中,因此您不受大小的限制。然后每行数据都有一个输入区域。这个输入区域可以是两行数据,所以它是分开的。或者你可以有一个弹出对话框。使用这两种方法中的任何一种,您都不会将自己限制在水平空间中,这也可以在未来进行更轻松的更改。
    猜你喜欢
    • 2013-12-25
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    • 2011-11-13
    • 2013-06-13
    • 2023-04-04
    • 2018-01-06
    • 1970-01-01
    相关资源
    最近更新 更多