是否可以使用涵盖Windows任务栏的非全屏Java应用程序?

时间:2018-06-19 15:20:19

标签: java java-8 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);
}
}

1 个答案:

答案 0 :(得分:0)

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

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

如果您仍然希望能够在这两个窗口下方切换至其他窗口,则可以向每个帧添加WindowFocusListener,如果焦点丢失,它将检查两个帧中的任何一个是否聚焦,以及是否否,setAlwaysOnTop(false)。同样,您必须将其重新启用为焦点增益。但是,由于触发这些事件的顺序,这有点麻烦,并且实现起来并不那么简单。下面的想法,但是您可能需要改进它:

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);