Frank
Frank

Reputation: 31096

How to find the JTextField in focus in Java?

In my Java Swing app, I have multiple JTextFields for dates, there is a JButton when clicked, it will open a calendar to pick a date, and the date string should be inserted into one of the JTextFields, so I want to design the program so that user first clicks in a date JTextField he wants to input a date [ get focus on that field and remember it ], the program saves the JTextField as target component, then that component is passed to the calendar object to input the picked date. So far I can hard code the program so it can input any date string I pick in to a certain JTextField I've hard coded with, but the problem is how to remember the JTextField user clicked on ? So I don't have to hard code it.

I've tried : Date_Field.getDocument().addDocumentListener(A_Listener); It won't get the focus until user starts typing in it.

I've also tried :

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

Also didn't work, because when user clicked on it, there is no action yet [ therefore no focus ] until user starts typing.

So what's a way to get the JTextField when user JUST clicks on it without typing anything ?

enter image description here

Upvotes: 0

Views: 735

Answers (3)

Frank
Frank

Reputation: 31096

Thanks for the answers and suggestions, but they are not what I was looking to find. Too much trouble and I don't have enough space in my app to add a button to each field, even if I do have enough space, they look too busy for dozens of fields each has it's own button, I want to clean simple look and yet still functions the way I like, so I did some search and found the ideal answer, here is how to achieve it :

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.

Upvotes: 1

camickr
camickr

Reputation: 324118

The suggestion by MadProgrammer is the way you should be solving the problem. It is the common UI that you will see in other application.

How to find the JTextField in focus in Java?

However to answer your more general question above when dealing with text components you can create an Action that extends from TextAction. The TextAction has a getFocusedComponent() method which returns the last text component with focus.

For example:

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

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

So typically you would use this class for creating a JMenuItem and then add the menu item to a JMenu on your JMenuBar. This is in fact how the cut/copy/paste Actions of the JDK work.

Again, I don't recommend it as a solution for this problem, but for future problems when you want to share an Action between multiple text components.

Also, when you use this approach the getFocusedComponent() method will return any text component so you can't be guaranteed that the last component to have focus would be one of your date fields. Another reason not to use this approach.

Upvotes: 3

MadProgrammer
MadProgrammer

Reputation: 347214

Combine both the JTextField and JButton into a custom component (maybe a JPanel) and isolate the functionality within it. This way, the button is ALWAYS associated with a given JTextField and you don't care about which field was "focused" last

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

}

Then you can create as many of these as you want and add them to whatever container you want

Upvotes: 3

Related Questions