«Всегда на вершине» Windows с Java

85

Есть ли в Java способ, чтобы окно было «Всегда наверху», независимо от того, переключает ли пользователь фокус на другое приложение? Я искал в Интернете, и все решения опираются на какой-то интерфейс JNI с собственными привязками. Неужели это не единственный способ сделать это? .. Или нет?

Лапли Андерсон
источник

Ответы:

159

Попробуйте этот метод Windowкласса:

Window.setAlwaysOnTop (логический)

Он работает так же, как и по умолчанию в диспетчере задач Windows: переключитесь на другое приложение, но оно всегда отображается сверху.

Это было добавлено в Java 1.5

Образец кода:

import javax.swing.JFrame;
import javax.swing.JLabel;

public class Annoying {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Hello!!");

        // Set's the window to be "always on top"
        frame.setAlwaysOnTop( true );

        frame.setLocationByPlatform( true );
        frame.add( new JLabel("  Isn't this annoying?") );
        frame.pack();
        frame.setVisible( true );
    }
}

альтернативный текст

Окно остается наверху, даже когда не активно

OscarRyz
источник
3
Вы могли подумать, что простой поиск по запросу «Java-приложение всегда наверху» даст такой ответ, но он не смог его найти. Спасибо.
Лапли Андерсон
46
Угадай, что. Теперь это так !! :) Это приводит вас сюда! google.com/search?&q=java+application+always+on+top
OscarRyz
Это просто и здорово. Я тоже искал что-то подобное, но не знал, что они реализовали это в Java 1.5. Спасибо за публикацию.
Кушал Паудьял
2
К сожалению, это не работает для меня при запуске полноэкранного приложения, такого как видеоигра. Кто-нибудь знает, как заставить его подняться на вершину в этой ситуации?
Dream Lane
1
@Dream lane, я бы, наверное, спросил это как новый вопрос
rogerdpack
11

По моим наблюдениям, я обнаружил, что привилегия AlwaysOnTop предоставляется самому последнему процессу, который требует, чтобы он всегда был наверху.

Итак, если у вас есть приложение, которое, setAlwaysOnTop(true)а затем другое приложение использует эту опцию, привилегия предоставляется второму приложению. Чтобы обойти это, я установил setAlwaysOnTop(false)и снова setAlwaysOnTop(true)всякий раз, когда какое-либо окно появляется поверх текущего окна.

Я проверил это с помощью wordwebin windows. WordWeb - одно из приложений, использующих AlwaysOnTopопцию изOS

Я не уверен, правильно ли это работает с вашим игровым сценарием.

Предупреждение : я не знаю о побочных эффектах.

Вот пример кода:

import java.awt.event.*;

import javax.swing.*;

public class MainWindow extends JFrame implements WindowFocusListener
{
    public MainWindow()
    {
        addWindowFocusListener(this);
        setAlwaysOnTop(true);
        this.setFocusable(true);
       // this.setFocusableWindowState(true);
        panel = new JPanel();
        //setSize(WIDTH,HEIGHT);
        setUndecorated(true);
        setLocation(X,Y);
        setExtendedState(MAXIMIZED_BOTH);
        setVisible(true);
    }

    public void windowGainedFocus(WindowEvent e){}
    public void windowLostFocus(WindowEvent e)
    {
        if(e.getNewState()!=e.WINDOW_CLOSED){
            //toFront();
            //requestFocus();
            setAlwaysOnTop(false);
            setAlwaysOnTop(true);
            //requestFocusInWindow();
            System.out.println("focus lost");
        }

    }

    private JPanel panel;
    private static final int WIDTH = 200;
    private static final int HEIGHT = 200;
    private static final int X = 100;
    private static final int Y = 100;

    public static void main(String args[]){
              new MainWindow();}
    }
розовая пантера
источник
Снова установить для него значение false и true, когда появляется другое окно, не похоже на работоспособное решение по одной простой причине - что, если другое приложение сделает то же самое?
Trejkaz
@Trejkaz Ну, это верная точка зрения. Я больше не занимаюсь свингом.
pinkpanther
Это отлично работает для моего варианта использования! Ключевым моментом была установка его обратно на false.
рококо
0

не используйте setFullScreenWindow, просто получите размер экрана, а затем setSize, и все будет хорошо.

X.Zhang
источник
Это ответ или комментарий?
Failed Scientist
@FailedScientist - прославленный комментарий
clankill3r