0

I have two textfields and I control values user enters to that textfields. For both of the textfields I use focusLost. However, for example, when the user not enters any value (one of the controls) and clicks other textfield I get first and second textfields control's information message. I mean after focus lost from the first text field, the second text field's focusLost be triggered. Why this happens? How to prevent this?

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.border.*;

public class Test extends JFrame
{
    private JPanel pa;
    private JTextField myTF1, myTF2;

    public static void main(String[] args) {
       EventQueue.invokeLater(new Runnable() {
           public void run() {
               try{
                  Test frame = new Test();
                  frame.setVisible(true);
               }
               catch(Exception e) {
                   e.printStackTrace();
               }
          }
       });
    }



    public Test()
    {
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       setBounds(100,100,450,300);
       pa = new JPanel();
       pa.setBorder(new EmptyBorder(5,5,5,5));
       setContentPane(pa);
       pa.setLayout(null);

       myTF1 = new JTextField();
       myTF1.addFocusListener(new FocusListener()
       {
          public void focusLost(FocusEvent arg)
          {
             if(myTF1.getText.equals(""))
                JOptionPane.showMessageDialog(null, "Error1", "Error", JOptionPane.ERROR_MESSAGE);
          }

          public void focusGained(FocusEvent arg)
          {
            // This is empty.. I don't need it..
          }
       });
       myTF1.setBounds(24,13,116,22);
       pa.add(myTF1);
       myTF1.setColumns(10);

       myTF2 = new JTextField();
       myTF2.addFocusListener(new FocusListener()
       {
           public void focusLost(FocusEvent arg)
           {
              if(myTF2.getText.equals(""))
                 JOptionPane.showMessageDialog(null, "Error2", "Error", JOptionPane.ERROR_MESSAGE);
           }

           public void focusGained(FocusEvent arg)
           {
             // This is empty.. I don't need it..
           }
       });
       myTF2.setBounds(24,48,116,22);
       pa.add(myTF2);
       myTF2.setColumns(10);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). – Andrew Thompson Dec 27 '17 at 08:59

1 Answers1

1

When the option pane is opened, the option pane gains the focus, stealing it from either of the text fields that has it at that moment.

One approach to solving this is to display the error messages in a label within the main GUI. Here is an example:

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.border.*;

public class Test2 extends JFrame {

    private JTextField myTF1, myTF2;
    private JLabel output = new JLabel("Enter a value in both field 1 & field 2");

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Test2 frame = new Test2();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public Test2() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationByPlatform(true);
        JPanel gui = new JPanel(new BorderLayout(5,5));        
        gui.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(gui);

        JPanel pa = new JPanel(new GridLayout(0, 1, 5, 5));
        gui.add(pa, BorderLayout.LINE_START);
        gui.add(output, BorderLayout.PAGE_END);

        myTF1 = new JTextField(10);
        myTF1.addFocusListener(new FocusListener() {
            public void focusLost(FocusEvent arg) {
                if (myTF1.getText().equals("")) {
                    output.setText("Error: Field 1 must have a value!");
                }
            }

            public void focusGained(FocusEvent arg) {
                // This is empty.. I don't need it..
            }
        });
        myTF1.setBounds(24, 13, 116, 22);
        pa.add(myTF1);

        myTF2 = new JTextField(10);
        myTF2.addFocusListener(new FocusListener() {
            public void focusLost(FocusEvent arg) {
                if (myTF2.getText().equals("")) {
                    output.setText("Error: Field 2 must have a value!");
                }
            }

            public void focusGained(FocusEvent arg) {
                // This is empty.. I don't need it..
            }
        });
        myTF2.setBounds(24, 48, 116, 22);
        pa.add(myTF2);

        pack();
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • So what the solution is? I added FlowLayout from design mode in Eclipse but problem continues – sanallhesap4 Dec 27 '17 at 10:19
  • I made a comment and an answer. The comment had nothing to do with solving the problem you are asking about, that's why it is a comment, not an answer. Using a flow layout may well fix the problem identified in the comment, but it does not address the main problem being asked about. The answer to your question might be approached in a variety of ways. One way is to add a (non-focusable) `JLabel` to the main GUI to display errors. Since it won't steal the focus, it will avoid two error messages being shown to the user. – Andrew Thompson Dec 27 '17 at 12:36
  • See the edit to my answer. It includes an example of using a label to display errors. – Andrew Thompson Dec 27 '17 at 12:50
  • Can you please share other solution approaches? – sanallhesap4 Dec 27 '17 at 14:06