我有一个非常基本的JPanel
,它设置在自己的JFrame
。
JPanel implements actionlistener
和overrides paintcomponent
。
我在paintcomponent方法中绘制了一堆东西,只是形状和多边形,大多数是固定的,但是旋转的是2个组件。这是通过计时器完成的。
计时器是Swing Timer
;
修正后我的意思是没有可能影响其位置的变量。
该类有一个启动计时器的StartTimer (StartTheCountdown())
方法。在每个计时器勾选时,执行的操作是它将角度增加一个固定的数字,然后它要求重新绘制窗口。
这是为了旋转未修复的几个组件。 (我在代码中留下了你要看的内容)
我遇到的问题是,如果你调整窗口大小,它会导致计时器滞后,因此旋转不会在适当的时间内发生。当你停止调整大小时,它会恢复正常。
如果你只是做一个快速的单一拖动并调整其大小不明显,但只是为了测试,如果我点击并按住并在屏幕上疯狂地拖动几秒钟,当我放开它显着滞后时,几乎就像它来到停下来,只有当我放手时才会继续。
我读过有关使用不同线程绘制和执行某些任务的信息,SwingWorker?但我不太确定如何在我的情况下使用它。
有关如何防止这种滞后的任何提示?
编辑:我添加了准备编译并按原样运行的新代码。
如果让它继续运行,箭头会在30秒后停在底部。如果你持续调整窗口大小一秒左右,计时器会在30秒后停滞不前,它还没到达底部。调整大小时的这种滞后是我试图阻止的。
import java.awt.* ;
import java.awt.event.*;
import javax.swing.*;
import java.awt.geom.*;
class guidemo{
JFrame clockscreen = new JFrame();
JPanel clockpanel = new JPanel(new GridLayout(1,1));
Theclock clock ;
guidemo ()
{
clock = new Theclock();
clockscreen.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
clockscreen.setTitle( "Countdown" );
clockscreen.setLocation(0,0);
clockscreen.setSize(830,830);
clockscreen.add(clockpanel);
clockpanel.add(clock);
clockscreen.setVisible(true);
clock.StartTheCountdown();
}
public static void main(String[]args)
{
//Setup demo
guidemo demo = new guidemo();
}
}
class Theclock extends JPanel implements ActionListener
{
Timer clockticker = new Timer(40,this);
double theta = 0;
public void StartTheCountdown(){
clockticker.start();
}
public void StopTheCountdown(){
clockticker.stop();
}
public void paintComponent(Graphics gc)
{
super.paintComponent(gc);
Graphics2D g2d = (Graphics2D)gc;
AffineTransform tx = new AffineTransform();
/*
There are lots of other graphics being drawn here
like ovals and rectangles etc but they are not affected
by the incrementing theta. So I removed them.
*/
tx.rotate((double)theta*(3.14/180), 400, 400);
g2d.setTransform(tx);
//Arrow border
g2d.setColor(new Color(159,131,154));
Polygon p = new Polygon();
p.addPoint(350,400);
p.addPoint(400,200);
p.addPoint(450,400);
g2d.fill(p);
}
public void actionPerformed(ActionEvent e)
{
theta += 0.25;
System.out.println(theta);
this.repaint();
if(theta == 180){
StopTheCountdown();
}
}
}
答案 0 :(得分:2)
有关如何防止这种滞后的任何提示?
将动画的静态部分存储在BufferedImage
中。在绘画时,绘制图像,然后将旋转的部分添加到顶部。
答案 1 :(得分:1)
我在Windows 7上使用JDK7时没有注意到任何问题。当我不断调整框架大小时,对象会继续旋转。这可能是版本/平台问题。
如果没有重新绘制那么问题可能是EDT滞后而且并非所有事件都是由Timer生成的,因为默认是使用setCoalesce(true),如果EDT滞后,它会将多个事件组合成一个
所以你可以尝试使用:
timerClock.setCoalesce(false);
如果这不起作用,那么您可以手动管理适当的旋转角度。这不仅仅是每次计时器触发时都添加0.25。
相反,您可以保持计时器启动的计时器。当计时器触发时,您将获得当前时间,并根据自计时器启动以来经过的时间确定适当的角度。这样,如果EDT陷入困境,当下一个Timer事件被触发时,你将“跳转”到适当的位置。