Swing: как предотвратить кражу фокуса из других приложений при вызове setVisible (true) - PullRequest
0 голосов
/ 06 февраля 2020

Я хочу, чтобы мое приложение Java Swing не могло украсть фокус у других приложений.

В некоторых случаях приложение будет отображать всплывающее окно, которое наследуется от JDialog, и показ этого всплывающего окна может быть вызван событиями, которые не были активированы пользователем. Я хочу убедиться, что при отображении всплывающего окна приложение не крадет фокус у других приложений.

Я обнаружил проблему до того момента, когда на JDialog вызывается setVisible (true). Эта проблема также воспроизводится с помощью JFrame, см. Пример кода ниже.

В некоторых системах вызов setVisible (true) приводит к тому, что все приложение выходит на передний план и захватывает фокус. В некоторых системах это приводит только к мигающему значку на панели задач, что представляет меньшую проблему, но служит индикатором того, что приложение пыталось украсть фокус.

Даже на том же Windows Версия (10) Я наблюдал оба поведения. Что я могу сделать, чтобы это исправить?

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import java.awt.Dimension;
import java.awt.HeadlessException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class FocusThief extends JFrame {
    public FocusThief() throws HeadlessException {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        JButton button = new JButton("click me and cover the window with another app");
        add(button);
        /*
         * Commented code below represents some (unsuccessfull attempts to prevent focus stealing
         */
//        setAlwaysOnTop(false);
//        setAutoRequestFocus(false);
//        setFocusableWindowState(false);

        button.setPreferredSize(new Dimension(400, 400));
        pack();
        button.addActionListener(e -> {
                    scheduledExecutorService.schedule(
                            () ->
                                    SwingUtilities.invokeLater(
                                            () -> setVisible(true)), 5L, TimeUnit.SECONDS);
                }
        );
    }

    public static void main(String[] args) {
        FocusThief focusThief = new FocusThief();
        focusThief.setVisible(true);
    }
}
...