Robert Kock
Robert Kock

Reputation: 6008

TextField loses focus to other window

Within a java-swing application, I have a textfield with some kind of help-popup.
I.e., when the user double clicks with the mouse within the textfield, this popup (implemented as an undecorated JFrame) is shown.

As soon as the textfield loses the focus, this popup is hidden again.
The problem is that showing this popup, the focus moves automatically to that frame, firing a lostFocus event on the textfield. This of course, closes the popup again.

I would like the lostFocus event to be triggered only if the textfield loses its focus to another component within the same window.

Any idea how to accomplish this?

Upvotes: 0

Views: 425

Answers (2)

Robert Kock
Robert Kock

Reputation: 6008

The solution is easier than I thought:
Within the focusLost callback, check the isTemporary() flag.
If set, ignore the event.

UPDATE:
If the ifTemporary() flag is set, determine the component that gains the focus (by means of getOppositeComponent()).
If that component if null, or its parent window is not our popup frame, than close the popup anyway.

Upvotes: 1

mr mcwolf
mr mcwolf

Reputation: 2850

Check which object has received the focus and hide the window depending on it.

this is a rough example

public class MainFrame extends JFrame {

    private JWindow popupWindow;

    public MainFrame() throws HeadlessException {
        super("Main Frame");
        createGUI();
    }

    private void createGUI() {
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setPreferredSize(new Dimension(600, 400));

        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));

        JTextField hintTextField = new JTextField();

        popupWindow = new JWindow(this);
        popupWindow.getRootPane().setBorder(BorderFactory.createLineBorder(Color.RED));
        popupWindow.getRootPane().setLayout(new BorderLayout());
        popupWindow.getRootPane().add(hintTextField, BorderLayout.CENTER);

        for(int i = 0; i < 10; i++) {
            JTextField textField = new JTextField();
            textField.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if(e.getClickCount() == 2) {
                        Point point = textField.getLocationOnScreen();
                        popupWindow.setBounds(point.x, point.y + textField.getPreferredSize().height, 200, 200);
                        popupWindow.setVisible(true);
                    }
                }
            });

            textField.addFocusListener(new FocusAdapter() {
                @Override
                public void focusLost(FocusEvent e) {
                    if(e.getOppositeComponent() != hintTextField) {
                        popupWindow.setVisible(false);
                    }
                }
            });

            panel.add(textField);
        }

        add(panel, BorderLayout.PAGE_START);

        pack();
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new MainFrame().setVisible(true));
    }
}

Upvotes: 0

Related Questions