是否AWT / Swing的取消绘制操作,如果在显示器关闭? [英] Does AWT/Swing cancel painting operations if the monitor is off?
问题描述
我遇到了摇摆的问题,只有当电脑显示器断电时,但我的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 andWINDOW_DEACTIVATED
on sleep. If so, you could extendJDialog
andrepaint()
inwindowActivated()
.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屋!