当 Java 不在顶部时,JDialog 不专注于 OSX

问题描述 投票:0回答:2

在 OSX 中,当 Java 程序不在前面时,我的 JDialog 不聚焦。我如何实现这一目标?

我有以下测试程序来说明该场景(在底部),从终端使用

javac Test.java && java Test
运行。

当终端输出“Started first”时,会将焦点转移到Java程序上。我通过单击终端(或其他程序)从启动的 Java 程序中移除焦点。显示有“第二个测试”文本的第二个 JDialog 将不会获得焦点。即使我设置了也是一样的

dialog.setAlwaysOnTop(true);

当我在看到“首先启动”后将 Java 程序保留在顶部时,带有“第二次测试”文本的 JDialog 正确聚焦(即不单击其他位置以便启动的 Java 程序位于顶部)。

请注意,我的 Java 程序没有 Swing UI。它在后台运行并弹出 JDialog 来接受用户输入。这在 Windows 和 Linux 上都可以正常工作(无论当时哪个应用程序处于焦点状态,创建的 JDialog 都会获得焦点)。

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());
    }
}
java swing jdialog
2个回答
0
投票

我不喜欢当前的答案,因为它非常hacky。我发现这个解决方案似乎对我很有效。我会在

dialog.setVisible(true)
之前调用它。

public static void foregroundApp() {
    if (Desktop.isDesktopSupported()) {
        Desktop desktop = Desktop.getDesktop();
        try {
            desktop.requestForeground(true);
        } catch (UnsupportedOperationException e) {}
    }
}

-1
投票

我最终使用了TT答案这里

基本上的想法是使用 java.awt.Robot 移动鼠标并单击弹出对话框以获得焦点。

它在大多数情况下都有效,但是当您有多个屏幕时,鼠标移动很奇怪,因此需要特殊情况处理。

© www.soinside.com 2019 - 2024. All rights reserved.