I've got a problem which I just can't seem to get around involving a small animation. For a project we are designing a J9 application to run on a PDA (DELL Axim X51). The problematic code (shown below) is when a mouse click is detected to run a small animation in a nested panel. If the animation is run independently of the mouse click, it works fine and repaints perfectly. When the method is called when a mouse click is recognized the repaint at every animation interval us ignored and only once the animation is completed will the panel be repainted.
我有一个问题,我似乎无法绕过涉及一个小动画。对于一个项目,我们正在设计一个在PDA上运行的J9应用程序(DELL Axim X51)。有问题的代码(如下所示)是指在检测到鼠标单击以在嵌套面板中运行小动画时。如果动画独立于鼠标单击运行,它可以正常工作并重新绘制完美。当识别出鼠标点击时调用该方法时,我们会忽略每个动画间隔的重绘,并且只有动画完成后才会重新绘制该面板。
I think it might have something to do with when a mouse click is recognized the application is synchronized with itself stopping any internal method calls to paint OR that the paint operation does not have high enough priority over the mouse click.
我认为它可能与识别鼠标单击时应用程序与其自身同步停止任何内部方法调用以绘制或者绘制操作的优先级不高于鼠标单击时有关。
My code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Panel;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class StatusLoader extends Panel implements Runnable{
int progress;
public static void main(String[] args) {
Frame f = new Frame();
StatusLoader mp = new StatusLoader();
mp.setBackground(Color.yellow);
f.add(mp);
f.setSize(300,300);
f.show();
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
mp.start();
}
public void start(){
Thread t = new Thread(this);
t.run();
}
public void run(){
for (int i = 0; i < 10; i++) {
progress+=10;
this.repaint(0);
System.out.println(i);
try{
Thread.sleep(100);
}catch(InterruptedException ex){}
}
}
public void paint(Graphics g){
System.out.println("called repaint");
g.setColor(Color.red);
g.setFont(new Font("Sansserif",2,24));
FontMetrics fm = g.getFontMetrics();
int stringWidth = fm.stringWidth("Loading");
g.drawString("Loading", getWidth()/2-stringWidth/2, getHeight()/2);
g.setFont(new Font("Sansserif",2,12));
fm = g.getFontMetrics();
stringWidth = fm.stringWidth("Map ziles for the new zoom level");
g.drawString("Map tiles for the new zoom level", getWidth()/2-stringWidth/2, getHeight()/2+30);
g.drawRect(getWidth()/2-100, getHeight()/2+60, 200, 10);
g.setColor(Color.blue);
g.fillRect(getWidth()/2-100, getHeight()/2+60, progress*2, 10);
}
}
1 个解决方案
#1
In StatusLoader.start
, you use Thread.run
instead of Thread.start
. That means StatusLoader.run
is executed on the events thread, which is a Very Bad Thing. Change it to t.start()
.
在StatusLoader.start中,您使用Thread.run而不是Thread.start。这意味着StatusLoader.run在事件线程上执行,这是一个非常糟糕的事情。将其更改为t.start()。
#1
In StatusLoader.start
, you use Thread.run
instead of Thread.start
. That means StatusLoader.run
is executed on the events thread, which is a Very Bad Thing. Change it to t.start()
.
在StatusLoader.start中,您使用Thread.run而不是Thread.start。这意味着StatusLoader.run在事件线程上执行,这是一个非常糟糕的事情。将其更改为t.start()。