4

I want to set the focus on a specific JTextField which is passed to the JOptionPane as Object Message. Here is my code (I want the focus on txt2 but the focus always is on txt1):

import java.awt.*;
import java.util.*;
import javax.swing.*;
public class TextArea extends JPanel
{
    private JTextArea txt1 = new JTextArea();
    private JTextArea txt2 = new JTextArea();
    public TextArea()
    {
        setLayout(null);
        setPreferredSize(new Dimension(200,100));
        txt1.setBounds (20, 20, 220, 20);
        txt2.setBounds (20, 45, 220, 20);
        txt1.setText("Text Field #1");
        txt2.setText("Text Field #2");
        add(txt1);
        add(txt2);
        txt2.requestFocus();
    }
    private void display()
    {
        Object[] options = {this};
        JOptionPane pane = new JOptionPane();
        pane.showOptionDialog(null, null, "Title", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, txt2);
    }
    public static void main(String[] args)
    {
        new TextArea().display();
    }
}
Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
  • 1
    I've not seen this type of JOptionPane used in this way, and I'm not sure that it's the proper way to do this. why not use a JDialog? – Hovercraft Full Of Eels Jun 25 '11 at 14:36
  • There is nothing wrong with this approach. It saves reinventing the wheel by completely creating a custom dialog. All you need to do create is the custom panel. – camickr Jun 25 '11 at 14:43
  • @camickr: Rob, I have to disagree as if you look closely at his code it seems *very* odd (at least to me) that he's adding his JPanel into the Object[] options variable (the 7th parameter) of the JOptionPane showOptionDialog method, not into the Object variable (the second variable). Have you done it this way before? I know that I haven't. – Hovercraft Full Of Eels Jun 25 '11 at 14:51
  • @Eng Fouad, I'm disappointed you took the solution based on the posted code. It shows you just copy solutions rather than take the time to understand the other solutions given. I provided you with a simple one line solution that you can use without subclassing the component. Reusable solutions are generally preferred to custom solutions. You don'tlearn by copying solutions, you learn by understanding the suggestions given. – camickr Jun 25 '11 at 14:53
  • @Hovercraft & @camickr: sorry guys, I was concerned only about how I can set focus on certain JTextField and I wrote this (SSCCE) quickly – Eng.Fouad Jun 25 '11 at 14:56
  • Pete, I'm talking about the general solution of adding a JPanel containing multiple components to a JOptionPane. I didn't take a close look at the contructor used to see if it was the best option, but the option pane is designed to display any component and build the buttons for you. The link I provided in my answer shows the simplest way to add a panel to an option pane. – camickr Jun 25 '11 at 15:01
  • @Eng Fouad, my comment was not about the SSCCE (that was a good SSCCE you posted). My comment was about taking the time to understand the different solutions provided. – camickr Jun 25 '11 at 15:03
  • @camickr: I agree with the general technique of adding a JPanel as the Object parameter of a JOptionPane, no problem, but his use of it seems a bastardization of JOptionPane and prevents the ability to be able to select options which is the whole reason for using a showOptionDialog. – Hovercraft Full Of Eels Jun 25 '11 at 15:04
  • @Hovercraft, yes I would agree with that as well. The panel should be the second parameter, not part of the options. – camickr Jun 25 '11 at 15:15

4 Answers4

6

You could let the txt2 component request focus once it is added by overriding addNotify. Like this:

private JTextArea txt2 = new JTextArea() {
    public void addNotify() {
        super.addNotify();
        requestFocus();
    }
};

Here's a fully functional / tested version of your program:

import java.awt.Dimension;
import javax.swing.*;
public class Test extends JPanel {
    private JTextArea txt1 = new JTextArea();
    private JTextArea txt2 = new JTextArea() {
        public void addNotify() {
            super.addNotify();
            requestFocus();
        }
    };

    public Test() {
        setLayout(null);
        setPreferredSize(new Dimension(200, 100));
        txt1.setBounds(20, 20, 220, 20);
        txt2.setBounds(20, 45, 220, 20);
        txt1.setText("Text Field #1");
        txt2.setText("Text Field #2");
        add(txt1);
        add(txt2);
    }

    private void display() {
        Object[] options = { this };
        JOptionPane pane = new JOptionPane();
        pane.showOptionDialog(null, null, "Title", JOptionPane.DEFAULT_OPTION,
                JOptionPane.PLAIN_MESSAGE, null, options, txt2);
    }

    public static void main(String[] args) {
        new Test().display();
    }
}
aioobe
  • 413,195
  • 112
  • 811
  • 826
3

I gave you the answer in your last question (http://stackoverflow.com/questions/6475320/how-to-set-the-orientation-of-jtextarea-from-right-to-left-inside-joptionpane). The concept is the same. Think about the solution given and understand how it works so you can apply it in different situations.

If you still don't understand the suggestion then see DialogFocus for reusable code.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • +1 This works also, but aioobe answers the question first so I accept his answer. Thanks anyway :) – Eng.Fouad Jun 25 '11 at 15:03
  • 4
    @Eng Fouad, What do you mean first? I provided the answer 3 minutes earlier! Plus, I also gave you the concept yesterday. Anyway answer should be choosen by what makes sense in terms of reusability and other design considerations. You don't just accept an answer because someone posts code. You need to take the time to understand the implications of the code so you can use the code or its concepts in other situations. – camickr Jun 25 '11 at 18:32
2

Why not use a JDialog or JFrame for this purpose?

   public void display2() {
      JDialog dialog = new JDialog(null, "Title", ModalityType.APPLICATION_MODAL);
      dialog.getContentPane().add(this);
      dialog.pack();
      dialog.setLocationRelativeTo(null);
      txt2.requestFocusInWindow();
      dialog.setVisible(true);
   }
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
0

You could use a workaround proposed in JDK-5018574 bug report.

Instead of

txt2.requestFocus();

use

txt2.addHierarchyListener(e -> {
    if(e.getComponent().isShowing() && (e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0)
        SwingUtilities.invokeLater(e.getComponent()::requestFocusInWindow);
});

I modified the solution to use Java 8 features. For older versions of Java, see the original workaround.

Genhis
  • 1,484
  • 3
  • 27
  • 29