Awt / Swing - 框架在移动过程中不会重新绘制

时间:2014-12-19 11:58:46

标签: java swing repaint

我正在尝试为'Stack'创建一些带有图形的示例。 我希望Wagons到“Spawn”并在一条轨道中移动,这些是“堆栈”。 移动过程由'Wagon'本身完成。我已经尝试给Wagon一个引用我'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

旅行车:

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;


public class Window extends JFrame {

private Stack stack1 = new Stack(1);

public Window() {
    setSize(800, 400);
    setResizable(false);
    setLayout(null); //Not perfect, but it works for those little things
    setVisible(true);
    createTracks(); //Tracksgraphic made out of gray rects
}
public void addWagon(Wagon wagon) { //Is called when adding a Wagon
    this.add(wagon);
    stack1.addWagon(wagon);
}

public static void main(String[] args) { //main
    new Window();
}
}

Stack:

public class Stack {        

private int gleis; //gleis = german for track
private Wagon first = null;


public Stack(int g) {
    gleis = g;
}

public void addWagon(Wagon wagon) {
    if (first != null) {
        wagon.setNext(first);
    }
    first = wagon;
    first.moveRight(gleis);
}

public void removeWagon(int id, Stack nextStack) {
    Wagon speicherFirst = first;
    first.moveLeft(null);
    first = first.getNext();

    while (speicherFirst.getID() != id) {
        speicherFirst.setNext(first);
        first.moveLeft(speicherFirst);
        speicherFirst = first;
        first = first.getNext();
    }

    nextStack.addWagon(speicherFirst);

    if (speicherFirst.getNext() != null) {
        speicherFirst = speicherFirst.getNext();
        while (speicherFirst!= null) {
            speicherFirst.moveRight(gleis);
            speicherFirst = speicherFirst.getNext();
        }
    }
}
public boolean hasID(int id) {
    return first.isID(id);
}
}

旅行车:

import javax.swing.*;
import java.awt.*;
import java.util.Random;


public class Wagon extends JPanel {     //Entspricht einem Canvas aus .awt 

private Wagon next;
private int id;

public Wagon(int i) {
    id = i;
    setSize(50, 20);
    Random r = new Random();
    setBackground(new Color(r.nextFloat(), r.nextFloat(), r.nextFloat()));
    setVisible(true);
}

public boolean isID(int i) {
    if (id == i) {
        return true;
    } else if (next == null) {
        return false;
    } else {
        return next.isID(i);
    }
}

public void setNext(Wagon n) {
    next = n;
}

public void moveRight(int gleis) {
    setLocation(getX(), gleis * 100);
    if (next != null) {
        while (next.getX() - getX() < 70) {
            next.moveRight(gleis);
            move(3);
        }
    } else {
        while (getX() < 700) {
            move(3);
        }
    }
}

public Wagon getNext() {
    return next;
}

public int getID() {
    return id;
}

public void moveLeft(Wagon previous) {

    if (previous == null) {
        while (getX() > 50) {
            move(-3);
        }
    } else {
        while (getX() - previous.getX() > 50) {
            move(-3);
        }
    }
}

public void move(int dir) {
    this.setLocation(getX() + dir, getY());
    try {
        Thread.sleep(20);
    } catch (InterruptedException e) {}
}

}

2 个答案:

答案 0 :(得分:1)

  

直到它停止时它仍然没有出现。

您的代码正在Event Dispatch Thread(EDT)上执行,该线程负责处理GUI事件和重新绘制GUI。 Thread.sleep()阻止GUI重新绘制自己,直到while / loop完成执行,所以你只能看到最后的绘画。有关详细信息,请阅读Concurrency上的Swing教程中的部分。

解决方案是使用Swing Timer来提供动画,而不是Thread.sleep()。

答案 1 :(得分:0)

您的代码中的任何地方似乎都没有replaint();调用。我会在moveLeft()moveRight()命令中使用它。

另一件事,你正在使用JPanels作为你的货车。我不会这样做,它会占用更多资源而且是不好的做法。除非有特殊原因,否则我会使用基本精灵图像,并将其加载到int[]数组,然后使用BufferedImage将该数组绘制到该屏幕,而不是运行x个JPanel。