Java join()方法存在问题
首先,这里有一些代码片段:Java join()方法存在问题,java,multithreading,Java,Multithreading,首先,这里有一些代码片段: public void startThread() { this.animationThread = new Thread(this); this.animationThread.start(); try { this.animationThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } @Over
public void startThread() {
this.animationThread = new Thread(this);
this.animationThread.start();
try {
this.animationThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
pirateMainAnimation.animate();
}
public void animate() {
for (int j = 0; j < 9; j++) {
try {
Thread.sleep(250);
} catch (InterruptedException e) {
break;
}
PirateAnimationPanel.getInstance().setCurrent(j);
PirateAnimationPanel.getInstance().repaint();
}
}
public void startThread(){
this.animationThread=新线程(this);
这个.animationThread.start();
试一试{
this.animationThread.join();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
@凌驾
public void run(){
盗版动画。动画();
}
public void animate(){
对于(int j=0;j<9;j++){
试一试{
睡眠(250);
}捕捉(中断异常e){
打破
}
PirateAnimationPanel.getInstance().setCurrent(j);
PirateAnimationPanel.getInstance().repaint();
}
}
我正在尝试制作一些图像的动画。我希望主线程等待动画线程完成,然后继续。我四处搜索,读了一些书,决定使用join()方法。它完美地等待线程完成,但我没有正确地设置动画。repaint()方法被调用2次而不是9次。我想问题可能是因为我使用了单身。这里是单例实现
import java.awt.Graphics;
import java.awt.MediaTracker;
import javax.swing.JPanel;
import uk.ac.aber.dcs.piratehangman.animation.PirateMainAnimation;
import uk.ac.aber.dcs.piratehangman.utilityclasses.AnimationThread;
@SuppressWarnings("serial")
public class PirateAnimationPanel extends JPanel {
private int current;
private MediaTracker mTracker;
private PirateMainAnimation pirateMainAnimation;
private AnimationThread animationThread;
private PirateAnimationPanel() {
this.current = 0;
this.pirateMainAnimation = new PirateMainAnimation();
mTracker = new MediaTracker(this);
this.animationThread = new AnimationThread();
setMediaTracker();
repaint();
}
private void setMediaTracker() {
for (int i = 0; i < 9; i++) {
mTracker.addImage(
this.pirateMainAnimation.getImagesForAnimation()[i],
this.pirateMainAnimation.getImagesForAnimationID()[i]);
try {
mTracker.waitForID(this.pirateMainAnimation
.getImagesForAnimationID()[i]);
} catch (InterruptedException e) {
System.out.println("Error loading image: " + i);
}
}
}
public void playAnimation() {
this.animationThread.startThread();
}
public void paintComponent(Graphics g) {
super.paintComponents(g);
System.out.println("called");
g.drawImage(this.pirateMainAnimation.getImagesForAnimation()[current],
0, 0, this);
}
private static class PirateAnimationPanelHolder {
private static final PirateAnimationPanel pirateAnimationPanel =
new PirateAnimationPanel();
};
public static PirateAnimationPanel getInstance() {
return PirateAnimationPanelHolder.pirateAnimationPanel;
}
public void setCurrent(int current) {
this.current = current;
}
public int getCurrent() {
return current;
}
}
导入java.awt.Graphics;
导入java.awt.MediaTracker;
导入javax.swing.JPanel;
进口uk.ac.aber.dcs.piratehangman.animation.PirateManimation;
导入uk.ac.aber.dcs.piratehangman.utilityplasses.AnimationThread;
@抑制警告(“串行”)
公共类PirateAnimationPanel扩展了JPanel{
私有电流;
私人媒体追踪者;
私人盗版;
私有AnimationThread AnimationThread;
private PirateAnimation Panel(){
该电流=0;
this.pirateManimation=新的pirateManimation();
mTracker=新的MediaTracker(本);
this.animationThread=新的animationThread();
setMediaTracker();
重新油漆();
}
私有void setMediaTracker(){
对于(int i=0;i<9;i++){
mTracker.addImage(
this.pirateManimation.getImagesForAnimation()[i],
this.pirateManimation.getImagesForAnimationID()[i]);
试一试{
mTracker.waitForID(this.pirateManimation
.getImagesForAnimationID()[i]);
}捕捉(中断异常e){
System.out.println(“加载图像时出错:+i”);
}
}
}
公开播放动画(){
this.animationThread.startThread();
}
公共组件(图形g){
超级组件(g);
System.out.println(“被调用”);
g、 drawImage(this.pirateManimation.getImagesForAnimation()[current],
0,0,这个),;
}
私有静态类PirateAnimationPanelHolder{
私有静态最终盗版图像面板盗版图像面板=
新的PirateAnimationPanel();
};
公共静态盗版ImationPanel getInstance(){
返回PirateAnimationPanelHolder.pirateAnimationPanel;
}
公共void setCurrent(int current){
这个电流=电流;
}
public int getCurrent(){
回流;
}
}
我想您的意思是paintComponent()方法只会被调用两次。此外,我认为如果将组件填充为背景色,则应该能够删除对super.paintComponents()的调用
repaint()方法仅将组件标记为脏组件,并在下一次绘制时请求重新渲染
我本来希望Swing线程能够在250ms内重新绘制,但我不确定还有哪些工作正在进行/呈现。您可能希望在动画之前调用MediaTracker.waitForAll()
虽然静态单例没有添加太多内容,但我认为它不会导致问题(在本例中)
更新:
所以问题在于join()位于Swing事件线程上,该线程阻止了组件的重新绘制。我建议进行如下调用,以在最后一个动画之后显示“新建游戏对话框”:
SwingUtilities.invokeLater(new Runnable() {
public void run() { showDialog(); }
})
“请注意,发布到的事件可以合并”,这可能解释了这种差异。此外,一定要在其上构建GUI。有关更详细的讨论,请参阅
附录:有一个很好的
SwingWorker
示例,可以简化卸载过程。考虑将代码作为问题的一部分发布,而不是放在其他地方。如果您需要帮助将其正确格式化,只需说出来,我很乐意为您编辑代码。我认为在这里发布代码只会妨碍您的工作stion。不管怎样,如果你能帮我做格式化,我会很高兴,因为我从来没有在这里发布过代码。谢谢:)。当然,要在上面格式化代码,只需在每行前面缩进四个空格。我会在代码中编辑,如果你点击“编辑”,你就能明白我的意思。欢迎来到StackOverflow顺便说一句:)还有,我注意到你了在你的文本中使用了制表符,这也必须被编辑掉,并替换为空格。无论如何,代码被编辑进去。为了回答你在评论中暗示的问题,不,这里的代码不会妨碍问题的解决,只要它的大小与你的一样,代码就会脱颖而出,因此很容易看到什么是代码,什么是代码问题。再次感谢你善良的先生:)。我很高兴受到这样的欢迎。:)谢谢你的回答,有趣的是,当对join()方法的调用从代码中删除时。它工作正常。非常奇怪,我会尝试你的想法。所以“动画线程”在上次调用repaint()后退出/停止可以在渲染完成之前进行。是否允许应用程序在连接和不连接的情况下继续?是什么触发了playAnimation(),它是从Swing线程(鼠标/按键事件或小程序)调用的?编辑:缺少wordplayAnimation()由JButton调用,但这取决于特定的条件。逻辑大致如下。用户在文本字段中输入一个单词,然后按下按钮