繁体   English   中英

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

[英]Awt/Swing - Frame doesn't repaint during move process

我正在尝试创建一个带有一些用于“堆栈”的图形的示例。 我想Wagons在一个轨道这是'stacks'为“再生侠”而动。 移动过程由“ Wagon”本身完成。 我已经尝试过为Wagon引用我的“ Frame”(称为“ Window”)以在每个循环中对其进行重新绘制,但是直到它停止时它仍然不显示。

车皮:

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();
}
}

堆:

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) {}
}

}

直到它停止它仍然不显示。

您的代码在事件分发线程(EDT)上执行,该线程负责处理GUI事件和重新绘制GUI。 Thread.sleep()防止GUI重新绘制自身,直到while / loop完成执行,因此您只能在最后看到绘制。 阅读Swing 并发教程中的有关更多信息的部分。

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

看来您实际上没有replaint(); 在代码中的任何地方调用。 我将在moveLeft()moveRight()命令中都使用它。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM