是否AWT / Swing的取消绘制操作,如果在显示器关闭? [英] Does AWT/Swing cancel painting operations if the monitor is off?

查看:113
本文介绍了是否AWT / Swing的取消绘制操作,如果在显示器关闭?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了摇摆的问题,只有当电脑显示器断电时,但我的Swing应用程序仍然在后台运行。看来,只要在显示器关闭时,Swing / AWT取消所有绘制操作,导致一些在GUI只要显示器重新开启可见的显示问题。

例如,当我使用自定义的JNI函数关闭显示器,随后打开一个简单的消息对话框,消息对话框是空白的显示器重新开启时:

但它的下一个重绘后正确描绘:

这是摇摆的预期行为?有没有一种方法来指示摆动,继续绘制屏幕,​​即使在显示器电源关闭?

编辑:下面是一个SSCCE:

 封装测试;进口javax.swing.JOptionPane中;
进口javax.swing.SwingUtilities中;公共类应用{
    公共静态无效的主要(字串[] args)抛出的Throwable
        的System.out.println(*****请关闭显示器在未来70秒*****);
        视频下载(1000L * 70);        SwingUtilities.invokeLater(Runnable的新(){
            @覆盖
            公共无效的run(){
                JOptionPane.showMessageDialog(NULL,测试);
            }
        });
    }
}

我使用的是64位Windows 7家庭premium SP1和64位Java 1.6.0_24。

编辑2:这里是我体验取消绘制操作的效果另一个程序:

 封装测试;引入静态com.mycompany.Util.turnOffMonitors;
进口java.awt.BorderLayout中;
进口java.awt.Color中;
进口java.awt.Container中;
进口java.awt.Dimension中;
进口javax.swing.JDialog中;
进口javax.swing.JFrame中;
进口javax.swing.JLabel中;
进口javax.swing.SwingUtilities中;公共类DialogTest扩展的JDialog {
    私人最终的JLabel标签;    公共DialogTest(){
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);        标签=新的JLabel(测试,JLabel.CENTER);
        label.setOpaque(真);        集装箱的contentPane =的getContentPane();
        contentPane.setLayout(新的BorderLayout());
        contentPane.add(BorderLayout.CENTER,标签);        this.set preferredSize(新尺寸(200,110));
        包();
        setLocationRelativeTo(NULL);
        调用setVisible(真);        线程t =新的Thread(){
            @覆盖
            公共无效的run(){
                turnOffMonitors();
                尝试{
                    视频下载(3000L);
                }赶上(InterruptedException的前){}                SwingUtilities.invokeLater(Runnable的新(){
                   @覆盖
                   公共无效的run(){
                       label.setBackground(Color.YELLOW);
                   }
                });
            }
        };
        t.start();
    }    公共静态无效的主要(字串[] args)抛出的Throwable
        SwingUtilities.invokeLater(Runnable的新(){
            公共无效的run(){
                新DialogTest();
            }
        });
    }
}

显示器关闭之前,我看到:

通过关闭显示器,标签背景颜色变成黄色的背景。然后,我将鼠标移动到重新开启显示屏上。该对话框在视觉上保持不变。只有后,我强制重绘(按ALT-Tab键,例如)做我看到黄色:

修改3:报道甲骨文为错误ID 7049597


解决方案

  

然后我开始计划和停止
  移动鼠标/输入。一个接一个
  分钟,屏幕关闭。一世
  又等了20秒的移动
  老鼠。显示器重新打开和
  我看到一个空白的消息对话框。


使用你的榜样,我不认为这对我的(非Windows)平台。你可以试试下面的例子中,它应该对睡眠 WINDOW_ACTIVATED 在唤醒和 WINDOW_DEACTIVATED 之间交替。如果是这样,你可以扩展的JDialog 重绘()的windowActivated()

 进口java.awt.EventQueue中;
进口java.awt.GridLayout中;
进口java.awt.event.ActionEvent中;
进口java.awt.event.WindowAdapter中;
进口java.awt.event.WindowEvent中;
进口javax.swing.AbstractAction中;
进口javax.swing.JButton中;
进口javax.swing.JDialog中;
进口javax.swing.JLabel中;/ ** @see http://stackoverflow.com/questions/6163606 * /
公共类DialogEventTest扩展的JDialog {    公共DialogEventTest(){
        this.setLayout(新的GridLayout(0,1));
        this.add(新的JLabel(对话事件的考验。JLabel.CENTER));
        this.add(的新的JButton(新AbstractAction(关闭){            @覆盖
            公共无效的actionPerformed(ActionEvent的五){
                DialogEventTest.this.setVisible(假);
                DialogEventTest.this.dispatchEvent(新WindowEvent(
                    DialogEventTest.this,WindowEvent.WINDOW_CLOSING));
            }
        }));
    }    私有静态类WindowHandler扩展WindowAdapter的{        @覆盖
        公共无效的windowActivated(WindowEvent五){
            的System.out.println(E);
        }        @覆盖
        公共无效的windowDeactivated(WindowEvent五){
            的System.out.println(E);
        }
    }    私人无效显示(){
        this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        this.addWindowListener(新WindowHandler());
        this.pack();
        this.setLocationRelativeTo(NULL);
        this.setVisible(真);
    }    公共静态无效的主要(字串[] args){
        EventQueue.invokeLater(新的Runnable(){            @覆盖
            公共无效的run(){
                新DialogEventTest()显示()。
            }
        });
    }
}

I am experiencing a problem with Swing that only occurs when the computer monitor is powered off, but my Swing application continues to run in the background. It seems that whenever the monitor is off, Swing/AWT cancels all painting operations, leading to a number of display issues in the GUI that are visible as soon as the monitor turns back on.

For example, when I turn off the monitor using a custom JNI function and subsequently open a simple message dialog, the message dialog is blank when the monitor turns back on:

But it paints correctly after the next repaint:

Is this the expected behavior of Swing? Is there a way to instruct Swing to continue drawing to the screen even if the monitor is powered off?

EDIT: Here is an SSCCE:

package test;

import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

public class App {
    public static void main(String[] args) throws Throwable {
        System.out.println("***** Please turn off the monitor in the next 70 seconds *****");
        Thread.sleep(1000L * 70);

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JOptionPane.showMessageDialog(null, "Test");
            }
        });
    }
}

I am using 64-bit Windows 7 Home Premium SP1 and 64-bit Java 1.6.0_24.

EDIT 2: Here is another program with which I experience the effect of "canceled painting operations":

package test;

import static com.mycompany.Util.turnOffMonitors;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class DialogTest extends JDialog {
    private final JLabel label;

    public DialogTest() {
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

        label = new JLabel("Test", JLabel.CENTER);
        label.setOpaque(true);

        Container contentPane = getContentPane();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(BorderLayout.CENTER, label);

        this.setPreferredSize(new Dimension(200, 110));
        pack();
        setLocationRelativeTo(null);
        setVisible(true);

        Thread t = new Thread() {
            @Override
            public void run() {
                turnOffMonitors();
                try {
                    Thread.sleep(3000L);
                } catch (InterruptedException ex) { }

                SwingUtilities.invokeLater(new Runnable() {
                   @Override
                   public void run() {
                       label.setBackground(Color.YELLOW);
                   }
                });
            }
        };
        t.start();
    }

    public static void main(String[] args) throws Throwable {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new DialogTest();
            }
        });
    }
}

Before the monitor shuts off, I see:

With the monitor off, the label background color is changed to yellow in the background. I then move the mouse to turn the monitor back on. The dialog is visually unchanged. It is only after I force a repaint (by ALT-TABbing, for example) do I see the yellow:

EDIT 3: Reported to Oracle as Bug ID 7049597.

解决方案

I then started the program and stopped moving the mouse/typing. After one minute, the screen turned off. I waited another 20 seconds to move the mouse. The monitor turned back on and I saw a blank message dialog.

Using your example, I don't see this on my (non-Windows) platform. You might try the example below, which should alternate between WINDOW_ACTIVATED on wake and WINDOW_DEACTIVATED on sleep. If so, you could extend JDialog and repaint() in windowActivated().

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;

/** @see http://stackoverflow.com/questions/6163606 */
public class DialogEventTest extends JDialog {

    public DialogEventTest() {
        this.setLayout(new GridLayout(0, 1));
        this.add(new JLabel("Dialog event test.", JLabel.CENTER));
        this.add(new JButton(new AbstractAction("Close") {

            @Override
            public void actionPerformed(ActionEvent e) {
                DialogEventTest.this.setVisible(false);
                DialogEventTest.this.dispatchEvent(new WindowEvent(
                    DialogEventTest.this, WindowEvent.WINDOW_CLOSING));
            }
        }));
    }

    private static class WindowHandler extends WindowAdapter {

        @Override
        public void windowActivated(WindowEvent e) {
            System.out.println(e);
        }

        @Override
        public void windowDeactivated(WindowEvent e) {
            System.out.println(e);
        }
    }

    private void display() {
        this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        this.addWindowListener(new WindowHandler());
        this.pack();
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new DialogEventTest().display();
            }
        });
    }
}

这篇关于是否AWT / Swing的取消绘制操作,如果在显示器关闭?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆