簡體   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