0

I have a GUI made using javax.swing and java.awt, the request focus was working on keeping the text field in focus, so that a user can just start with a keyboard. I then added buttons for each integer 0-9, aswell as a clear field button. However the focus now always starts on a button.

The focus still returns to the textField whenever I click a button or if I initiate the focus it remains in the textField, how can I fix this problem and have the focus on the text field everytime the window opens?

Example Number Buttons

JButton btn0 = new JButton("0");
        panel.add(btn0);
        btn0.setBounds(50, 360, 50, 50);
        btn0.setHorizontalAlignment(SwingConstants.CENTER);
        btn0.setForeground(Color.BLACK);
        btn0.setFont(new Font("Arial", Font.BOLD, 20));
        btn0.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String userIn = txtGuess.getText() + btn0.getText();
                txtGuess.setText(userIn);
            }
        });

textField Code

txtGuess = new JTextField();
        txtGuess.setBounds(325, 220, 100, 35);
        panel.add(txtGuess);
        txtGuess.setFont(new Font("Arial", Font.BOLD, 25));
        txtGuess.setHorizontalAlignment(SwingConstants.CENTER);
        txtGuess.setBackground(Color.decode("#206BA4"));
        txtGuess.setForeground(Color.decode("#EBF4FA"));
        txtGuess.setBorder(loweredBorder);
        txtGuess.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                checkGuess();
            }
        });

The end of checkGuess();

finally {
            txtGuess.requestFocus(); //sets focus to the text box after checking guess
            txtGuess.selectAll(); //highlights all text in the text field so UX is improved
            if (attempt >= 10) {
                lblOutput.setText("You lose! Try Again?");
                newGame();
            }
  • 2
    1. For best help, post a ***small*** (key word) program that compiles, runs, and demonstrates your problem, an [mcve]. 2. You appear to be using null layouts and `setBounds`, and while this is not causing your main problems, it will cause your future problems, and so I urge you not to go this route but to use layout managers. – Hovercraft Full Of Eels Mar 18 '18 at 12:54
  • 2
    And does this `newGame();` create an entirely new GUI window? If so, perhaps better is to more simply reset the current window to its original state. But again, difficult to say without your [MCVE](https://stackoverflow.com/help/mcve) code post. – Hovercraft Full Of Eels Mar 18 '18 at 13:04
  • I'm trying to figure out how to create the MCVE version to demonstrate the problem, thanks for the tip about this. Also no newGame(); simply resets the logic of the game and the GUI stays constantly open. – Stew-coder95 Mar 18 '18 at 13:08
  • Creating a decent MCVE is not all that easy, but often the effort reveals the problem to you yourself, since you're forced to expose the problem. – Hovercraft Full Of Eels Mar 18 '18 at 13:09

3 Answers3

1
txtGuess.requestFocus(); 

First of all you should not be using that method. Read the API for the method and it will tell you the better method to use.

how can I fix this problem and have the focus on the text field every time the window opens?

Focus should go to the component at the top left of the frame by default. If this isn't happening, then you are doing something strange.

If your text field is not the first component on the frame, then you can only set focus on it AFTER the GUI has been made visible.

Based on the code posted it looks like the text field is located above the button, so it should get focus. Maybe the problem is that you are using a null layout and the order you add components to the frame. We can't tell without a proper MCVE.

Other suggestions for your code:

  1. Don't use a null layout and setBounds(). You should not be manually setting a size/ Swing was designed to be used with layout managers.

  2. There is no need to create a unique ActionListener for every button. You can create a generic listener to be shared by every button. Check out: How to add a shortcut key for a jbutton in java? for a working example of this approach.

I'm trying to figure out how to create the MCVE version to demonstrate the problem

Its not a big mystery. You stated you had a frame with a text field and it worked. Then you added a button and it didn't work. So The MCVE will simply consist of a frame with a text field and button. The game logic is irrelevant to your question so it is not needed. So the MCVE should be about 10 - 15 lines of code.

camickr
  • 321,443
  • 19
  • 166
  • 288
0

The solution was to implement this code

frame.addWindowFocusListener(new WindowAdapter() {
            public void windowGainedFocus(WindowEvent e) {
                textfield.requestFocusInWindow();
            }
        });
0

The focus goes by default to the first focusable Component in the layout.

If you want to change this behaviour:

  • either follow the accepted answer
  • or add an AncestorListeneron the component you want to gain focus
  • or call pack() on the frame/dialog, request the focus textfield.requestFocusInWindow(); and then show the frame/dialog frame.setVisible(true);

See this other question that has been answered on SO, as well as this article that gives you the full answer.

nhaggen
  • 301
  • 2
  • 8