JFrame flash 图像 1/100 秒
JFrame flash image for 1/100 second
我有 JFrame,需要闪烁图像 10 毫秒(或显示器可以支持的最短时间)。
目前,这是我所做的:
我有一个 JFrame 和一个 JPanel 并覆盖了 paintComponent()
方法。当我需要刷新该图像时,我调用 repaint()
方法在 JFrame 上绘制图像,然后安排 next 再次调用 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毫秒都没有?
可能会发生很多事情...
- 调用
setVisible
和帧对用户实际可见的时间之间的时间...
- 设置事件调度线程的时间...
- 设置
Timer
和安排 TimerTask
的时间
- 请求重绘帧与重绘实际发生之间的时间
- 您请求重新绘制框架而不是实际显示图像的组件这一事实
- 系统上的其他一些activity,都在JavaAPIand/orOS...
内
您需要尝试缓解其中一些问题...
因此,不是在调用 setVisible
之后直接安排 TimerTask
,而是可以使用 WindowListener
,以便在 window 打开并开始时通知您然后计时器...
不要在调用 main
的线程中构建所有内容,而是确保从事件调度线程
的上下文中创建和更新 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();
}
}
});
}
}
我有 JFrame,需要闪烁图像 10 毫秒(或显示器可以支持的最短时间)。
目前,这是我所做的:
我有一个 JFrame 和一个 JPanel 并覆盖了 paintComponent()
方法。当我需要刷新该图像时,我调用 repaint()
方法在 JFrame 上绘制图像,然后安排 next 再次调用 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毫秒都没有?
可能会发生很多事情...
- 调用
setVisible
和帧对用户实际可见的时间之间的时间... - 设置事件调度线程的时间...
- 设置
Timer
和安排TimerTask
的时间
- 请求重绘帧与重绘实际发生之间的时间
- 您请求重新绘制框架而不是实际显示图像的组件这一事实
- 系统上的其他一些activity,都在JavaAPIand/orOS... 内
您需要尝试缓解其中一些问题...
因此,不是在调用 setVisible
之后直接安排 TimerTask
,而是可以使用 WindowListener
,以便在 window 打开并开始时通知您然后计时器...
不要在调用 main
的线程中构建所有内容,而是确保从事件调度线程
不要在框架上调用 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();
}
}
});
}
}