首页 > 解决方案 > 是否可以有一个覆盖 Windows 任务栏的非全屏 Java 应用程序?

问题描述

我正在尝试创建一个应用程序,它使用两个 JFrame,每个 JFrame 占据屏幕的一半。但我希望实现的是具有两个独立框架的“全屏”效果。

我尝试了各种方法,例如使用 JFrame api 的toFront方法等,但仍然不可行。

当用户与我的应用程序交互时,他们可以打开必须始终位于顶部的表单,即使单击 jframe 也是如此。目前,如果我将alwaysOnTop设置为 true,当我单击 jframe 时,表单将被推回框架后面。

这组代码(TestApp2)展示了我想要实现的全屏效果,即覆盖Windows任务栏。

package doubleframe;

import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;

public class TestApp2 {

public static void main(String[] args) {
    new TestApp2();
}

public TestApp2() {
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    int height = screenSize.height;
    int width = (screenSize.width);

    JFrame frame1 = new JFrame();
    frame1.setBounds(0, 0, width, height);
    frame1.setUndecorated(true);
    frame1.setVisible(true);
}
}

这组代码(TestApp)显示了我的应用程序是怎样的,但无法达到覆盖任务栏的效果。

package doubleframe;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class TestApp {

private int size = 2;

public static void main(String[] args) {
    new TestApp();
}

public TestApp() {
    initFrames();
}


private void initFrames() {
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    int height = screenSize.height;
    int width = (screenSize.width / size);

    JFrame frame1 = new JFrame();
    frame1.setBounds(0, 0, width, height);
    frame1.setUndecorated(true);
    frame1.setVisible(true);

    JPanel panel1 = new JPanel();
    panel1.setBackground(Color.GREEN);
    panel1.setBounds(0, 0, width, height);

    frame1.getContentPane().add(panel1);

    //frame 2
    JFrame frame2 = new JFrame();
    frame2.setBounds(width, 0, width, height);
    frame2.setUndecorated(true);
    frame2.setVisible(true);

    JPanel panel2 = new JPanel();
    panel2.setBackground(Color.BLUE);
    panel2.setBounds(width, 0, width, height);

    frame2.getContentPane().add(panel2);
}
}

标签: javajava-8jframe

解决方案


您可以将两个框架设置为始终位于顶部:

frame1.setAlwaysOnTop(true);
frame2.setAlwaysOnTop(true);

如果您仍然希望能够 alt-tab 到这两个下面的窗口,您可以在WindowFocusListener每个帧中添加一个,在焦点丢失时将检查两个帧中是否有任何一个被聚焦,如果没有,setAlwaysOnTop(false). 同样,您必须重新启用它以获得焦点。然而,由于这些事件被触发的顺序,这有点hacky并且实现起来并不那么简单。下面的想法,但你可能需要改进它:

WindowFocusListener listener = new WindowAdapter() {
    AtomicBoolean switchingOff = new AtomicBoolean();

    @Override
    public void windowGainedFocus(WindowEvent e) {
        if (!switchingOff.get() && !frame1.isAlwaysOnTop() && !frame2.isAlwaysOnTop()) {
            SwingUtilities.invokeLater(() -> {
                frame1.setAlwaysOnTop(true);
                frame2.setAlwaysOnTop(true);
            });
        }
    }

    @Override
    public void windowLostFocus(WindowEvent e) {
        SwingUtilities.invokeLater(() -> {
            if (!frame1.isFocused() && !frame2.isFocused()) {
                switchingOff.set(true);
                frame1.setAlwaysOnTop(false);
                frame2.setAlwaysOnTop(false);
                SwingUtilities.invokeLater(() -> switchingOff.set(false));
            }
        });
    }
};
frame1.addWindowFocusListener(listener);
frame2.addWindowFocusListener(listener);

推荐阅读