【问题标题】:Java - Screen turns black, when setting a JFrame to FullscreenJava - 将 JFrame 设置为全屏时,屏幕变黑
【发布时间】:2012-03-27 19:25:17
【问题描述】:

我正在尝试在 Canvas 上绘制一些东西,将其添加到 JFrame,然后将此 JFrame 设置为全屏。我的问题是:在全屏模式下我只看到黑屏。 在屏幕变黑之前,我很快就可以看到画布的粉红色背景。

直接在 JFrame 上绘图,然后将其设置为全屏效果非常好,我可以看到测试文本。我认为正确显示 Canvas 存在问题。

这是我的代码:

public class FullscreenTest extends Canvas {

    private JFrame mainFrame;

    public FullscreenTest(){
        this.mainFrame = new JFrame();
        JPanel contentPane = (JPanel) mainFrame.getContentPane();
        contentPane.add(this);
    }

    public void run(DisplayMode dm){
        setBackground(Color.PINK);
        setForeground(Color.WHITE);
        setFont(new Font("Arial", Font.PLAIN, 24));

        Screen s = new Screen();

        s.setFullScreen(dm, this.mainFrame);

        try {
            Thread.sleep(5000);
        } catch (InterruptedException exc) { exc.printStackTrace(); }

        s.closeFullScreenWindow();
    }

    public void paint(Graphics g){      
        g.drawString("This is some testtext", 200, 200);
    }

    public static void main(String[] args){
        DisplayMode dm = new DisplayMode(800, 600, 32, DisplayMode.REFRESH_RATE_UNKNOWN);
        FullscreenTest test = new FullscreenTest();
        test.run(dm);
    }
}

Screen.setFullScreen(DisplayMode dm, JFrame window) 方法的作用如下:

//graphicsDevice = GraphicsEnvironment.getLocalGraphicsEnvironment()
//                 .getDefaultScreenDevice();
public void setFullScreen(DisplayMode dm, JFrame window){
    window.setUndecorated(true);
    window.setResizable(false);
    graphicsDevice.setFullScreenWindow(window);

    if(dm != null && graphicsDevice.isDisplayChangeSupported()){
        graphicsDevice.setDisplayMode(dm);          
    }
}

有人知道为什么我在全屏模式下看不到 JFrame 的内容吗?

【问题讨论】:

  • 在调用 setFullScreen() 之后弹出 this.mainFrame.repaint() 调用有什么不同吗?我想知道更改为全屏是否会转储位,但它没有意识到需要重新绘制。
  • 不幸的是,这并没有改变任何东西。当屏幕切换到全屏模式时,我很快就会在屏幕变黑之前看到画布的粉红色背景(即使没有 repaint())。
  • 实际上,仔细想想,我认为问题在于使当前线程休眠 - 因为当前线程是 UI 线程,所以您实际上是在暂停 UI 线程,不允许它继续工作。尝试将 Thread.sleep() 从此类中取出并在调用 run() 后将其放入 main() - 然后添加一个单独的方法以再次缩小窗口。如果我的线程理论正确,那么睡眠是在应用程序线程上,而不是 UI 线程上。
  • 我很快尝试了,但这似乎也不能解决问题。短暂显示粉红色背景后,全屏仍然变黑。
  • 我找出了导致问题的原因:它是 DisplayMode 构造函数的位深度参数 (new DisplayMode(800, 600, 32, DisplayMode.REFRESH_RATE_UNKNOWN);) 虽然 32 位的位深度有效当我尝试将一个简单的 JFrame 设置为全屏时效果很好,似乎在全屏使用 32 位位深度的 Canvas 时出现问题。使用 16 位与我在问题中提供的源代码完美配合。不过,我真的不知道确切的问题是什么。

标签: java swing jframe awt fullscreen


【解决方案1】:

1) 你有三个一般性问题

  • 永远不要通过使用Thread.sleep(5000); 来阻止 EDT,而是使用 Swing Timer,演示 here

  • (如果不是真的有很重要的原因)不要混AWT with Swing剩下的是here,用JPanel代替Canvas(对于Canvas有没有paint方法,对于JPanel 有没有paintComponent)

  • 您的public void paint(Graphics g){ 是JFrame 而不是Canvas 并被Thread.sleep(5000); 锁定

2) Swing GUI 相关的应该包装成invokeLater() 含义

public static void main(String[] args){

更多内容请关注Initial Thread

3)in linked code example你可以了解如何在Swing中使用后台线程的演示

【讨论】:

  • 供参考,有一个相关的例子here。
【解决方案2】:

我同意 mKorbel 的观点(实际上,我已经让您的代码在他建议的更正下工作)。只需一个提示即可进一步获得更可预测的结果:在paint() 方法中控制颜色。背景的默认颜色可能在不同的系统上有所不同。在我的系统上,它在浅红色背景上绘制白色文本。但是如果它会在黑色背景上绘制黑色文本,测试看起来就像“不工作”。

【讨论】:

    【解决方案3】:

    嘿,我遇到了同样的问题,每次运行程序时屏幕都会变黑。 在绘画方法的部分,你写道,我认为它来自 Bucky 教程,顺便说一句很棒:

    public void paint(Graphics g){      
            g.drawString("This is some testtext", 200, 200);
        }
    

    你所要做的就是使用“超级”

    public void paint(Graphics g){
            super.paint(g);
            g.drawString("This is some testtext", 200, 200);
        }
    

    我自己试过了,效果很好。

    【讨论】:

    • super 正在使用超类中的所有方法并应用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多