java闪烁对象,频率稳定
我发现的所有其他问题似乎都与“无闪烁”有关,而我实际上想要一个闪烁 我正试图建立一个小应用程序,显示对象闪烁在一个给定的频率 下面是我正在尝试做的一个小的可行的例子。当前,我通过以给定频率执行的计划任务闪烁对象。在此任务中,我绘制对象,等待一半时间,然后删除它。这应该给我一个物体,它以给定的频率闪烁 然而,我发现即使在低至4Hz的频率下,闪烁也不再稳定。我认为这是因为Java不能保证在被要求时绘制屏幕,但允许它将某些绘制任务合并成一个。我不确定,但我想我读过类似的东西 我的问题是:如何制作一个频率高达屏幕刷新率一半的稳定闪烁对象java闪烁对象,频率稳定,java,swing,frequency,Java,Swing,Frequency,我发现的所有其他问题似乎都与“无闪烁”有关,而我实际上想要一个闪烁 我正试图建立一个小应用程序,显示对象闪烁在一个给定的频率 下面是我正在尝试做的一个小的可行的例子。当前,我通过以给定频率执行的计划任务闪烁对象。在此任务中,我绘制对象,等待一半时间,然后删除它。这应该给我一个物体,它以给定的频率闪烁 然而,我发现即使在低至4Hz的频率下,闪烁也不再稳定。我认为这是因为Java不能保证在被要求时绘制屏幕,但允许它将某些绘制任务合并成一个。我不确定,但我想我读过类似的东西 我的问题是:如何制作一个频
public class NewJFrame extends javax.swing.JFrame {
private final int FlashFreqHz = 4;
private java.util.Timer timer;
/**
* Creates new form NewJFrame
*/
public NewJFrame() {
initComponents();
startFlashing();
}
private class FlashingTask extends TimerTask{
@Override
public void run() {
int w=jPanel1.getWidth();
int h=jPanel1.getHeight();
try {
jPanel1.getGraphics().fillRect(10, 10, w/2, h/2);
Thread.sleep((1000/FlashFreqHz)/2);
jPanel1.getGraphics().clearRect(10, 10, w/2, h/2);
} catch(InterruptedException ex) {
ex.getStackTrace();
}
}
}
public void startFlashing() {
if(timer!=null) stopFlashing(); // running, must stop to get new position correct
timer = new java.util.Timer();
timer.scheduleAtFixedRate(new FlashingTask(), 0, 1000/FlashFreqHz); // 40 ms delay
}
public void stopFlashing() {
if (timer != null) {
timer.cancel();
timer = null;
jPanel1.repaint();
}
}
请检查,以下是我的“更正”代码:
import java.awt.event.ActionEvent;
import javax.swing.Timer;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
import java.awt.Graphics;
public class NewJFrame extends javax.swing.JFrame implements ActionListener{
private final int FlashFreqHz = 60;
private final Timer timer;
private boolean Flash = false;
FlashFrame FlashPanel;
/**
* Creates new form NewJFrame
*/
public NewJFrame() {
initComponents();
FlashPanel = new FlashFrame();
setContentPane(FlashPanel);
timer = new Timer(1000/FlashFreqHz,this);
timer.start();
}
class FlashFrame extends JPanel {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(Flash) {
g.fillRect(10, 10, getWidth()/2, getHeight()/2);
} else {
g.clearRect(10, 10, getWidth()/2, getHeight()/2);
}
}
}
@Override
public void actionPerformed(ActionEvent e) {
FlashPanel.repaint();
Flash = !Flash;
}
你觉得这个更好吗
我开始的问题也是遗留问题。虽然频率比我的“睡眠”方法稳定得多,但仍然存在一些明显的不稳定性,尤其是在更高的频率下
有什么可以做的吗?Thread.sleep()是一种固有的不稳定的计时方式,它不仅取决于它的运行方式,而且如果操作系统决定让jvm线程休眠一秒钟,Thread.sleep()任务将看不到使用getGraphics不是自定义绘制的方式。使用Java.util.Timer违反了Swing的单线程规则。看一看,您的更新代码很好。如果您仍然注意到不稳定性(顺便问一下,频率是多少?),这可能与摆动绘画机制无关。我的经验是,Swing每秒能够处理数千个事件,因此,当给定一个简单的绘制任务时,异步重新绘制能够获得非常高的帧速率(远大于监视器刷新)。实际上,我想到了一件可以尝试的事情,那就是调用计时器<默认情况下,code>javax.swing.Timer合并操作事件。虽然我不认为这真的会有多大区别,但我敢打赌你仍然在尝试高于显示器刷新率的频率(无论你做什么都无法显示)。嗨,谢谢你的回复,我将测试“合并”的想法,谢谢。监视器刷新率为60Hz,即使在20Hz闪烁率下,也会出现小的不连续性。正如我之前所说的,它现在好多了,可能还可以接受,我只是想知道它是否可以更容易地进一步改进。当然,将闪烁率提高到60Hz以上会产生虚假的结果:D