Skip to content
Advertisement

JDialog not focused on OSX when Java is not on top

My JDialog is not focused when the Java program is not in the front in OSX. How do I achieve this?

I have the following test program to illustrate the scenario (at the bottom), running using javac Test.java && java Test from a terminal.

When the terminal output “Started first”, it will change focus to the Java program. I remove focus from the launched Java program by clicking on the terminal (or some other program). The second JDialog shown with “Second test” text will not be focused. This is the same even if I set dialog.setAlwaysOnTop(true);

The JDialog with “Second test” text is correctly focused when I leave the Java program stay on top after seeing “Started first” (i.e. not clicking somewhere else so that the launched Java program is on top).

Note that my Java program doesn’t have a Swing UI. It runs in the background and pops up JDialog to take user input. This works fine on both Windows and Linux (the created JDialog is focused regardless of which application is in focus at the time).

public class Test {
    public static void main(String[] args) throws Exception {

        Thread t = new Thread() {
            @Override
            public void run() {
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        launch("First test");
                    }
                });
            }
        };
        Thread t2 = new Thread() {
            @Override
            public void run() {
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        launch("Second test");
                    }
                });
            }
        };

        t.start();
        System.out.println("Started first");
        Thread.sleep(5000);
        System.out.println("Started second");
        t2.start();
    }

    private static void launch(String title) {
        System.out.println("Showing");
        System.out.println(Thread.currentThread().getName());

        final JDialog dialog = new JDialog(null, "Test", ModalityType.APPLICATION_MODAL);
        dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        final JTextField searchBar = new JTextField(title);
        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
        panel.add(searchBar);
        dialog.add(panel);
        dialog.pack();
        dialog.setLocationRelativeTo(null);
        searchBar.requestFocus();
        SwingUtilities.invokeLater(new Runnable() {  
            public void run() { 
                searchBar.requestFocus();
            }
        });
        dialog.setVisible(true);
        System.out.println("Result is " + searchBar.getText());
    }
}

Advertisement

Answer

I ended up using TT answer here.

Basically the idea is to use java.awt.Robot to move the mouse and click on the popup dialog to gain focus.

It works most of the time, but mouse movement is weird when you have multiple screens so special case handling is needed.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement