我有JFrame,需要将图像闪烁10毫秒(或者显示器可以支持的最小值)。
目前,这就是我所做的:
我的 JFrame 带有 JPanel ,并带有覆盖的paintComponent()
方法。当我需要闪现该图片时,我调用repaint()
方法在 JFrame 上绘制图片,然后安排下一个再次调用repaint()
以删除10之后的图片毫秒。然而,这是一个长时间的闪光,这是裸眼非常明显。
这是我的代码:
public static boolean show = true;
public static void main(String[] args) {
final JFrame f = new JFrame("Test");
f.setUndecorated(true);
f.setAlwaysOnTop(true);
f.setFocusable(false);
JPanel c = new JPanel() {
@Override
public void paintComponent(Graphics g) {
if (show) {
try {
// I was too lazy to save the image as a variable ;)
g.drawImage(ImageIO.read(ClassLoader.getSystemResource("Puppy.png")), 1, 1, null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
super.paintComponent(g);
}
};
c.setOpaque(false);
c.setPreferredSize(new Dimension(1920, 1080));
f.getContentPane().add(c);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
com.sun.awt.AWTUtilities.setWindowOpaque(f, false);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
long time = System.nanoTime();
show = true;
f.repaint();
timer.schedule(new TimerTask() {
@Override
public void run() {
show = false;
f.repaint();
System.out.println(System.nanoTime() - time + Boolean.toString(show));
}
}, 10);
}
}, 1000, 1000);
}
问题:为什么帧会闪烁这么久,而不是10毫秒?
答案 0 :(得分:2)
可能会发生很多事情......
setVisible
与用户实际可见的时间之间的时间...... Timer
并安排TimerTask
您需要尝试缓解其中一些问题......
因此,不是在调用TimerTask
后直接安排setVisible
,而是可以使用WindowListener
,这样您可以在窗口打开时收到通知并启动计时器然后......
不要在调用main
的线程中构建所有内容,而是确保在Event Dispatching Thread的上下文中创建和更新UI
不要在框架上调用repaint
,而是重新绘制要重新绘制的实际组件...
使用java.util.Timer
代替使用javax.swing.Timer
,在修改UI状态时更安全
以下示例仅使用JLabel
呈现图像,并在javax.swing.Timer
刻度后删除它...
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
/**
*
* @author shane
*/
public class Test {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
try {
BufferedImage img = ImageIO.read(new File("C:\\hold\\thumbnails\\_MTCGAC__Pulling_Cords_by_Dispozition.png"));
JLabel label = new JLabel(new ImageIcon(img));
JFrame frame = new JFrame("Testing");
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
Timer timer = new Timer(10, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
frame.remove(label);
frame.revalidate();
frame.repaint();
}
});
timer.setRepeats(false);
timer.start();
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(label);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException exp) {
exp.printStackTrace();
}
}
});
}
}