我是 java swing 的新手,如果我的错误非常明显,请原谅我。我的代码在这里应该做的是创建一个 JFrame 并为两个并排向上移动穿过框架的盒子设置动画。但是,我只看到一个框(由 ElevatorOne
类创建的蓝色框)。绿色框(来自 ElevatorTwo
)没有出现。这是我的代码:
Execute
类(使用 main
方法):
public class Execute {
public static void main (String[ ] args) {
Thread thread1 = new Thread() {
public void run() {
ElevatorOne e1 = new ElevatorOne();
e1.createFrame(800, 600);
e1.addElevatorOne();
}
};
Thread thread2 = new Thread() {
public void run() {
ElevatorTwo e2 = new ElevatorTwo();
e2.addElevatorTwo();
}
};
thread1.start();
thread2.start();
}
}
ElevatorOne
类(绘制蓝色框的类):
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class ElevatorOne extends GUI{
int y = 400;
public void addElevatorOne() {
DrawElevatorOne drawE1 = new DrawElevatorOne();
frame.getContentPane().add(drawE1);
for(int i = 0; i < 300; i++) {
y--;
drawE1.repaint();
try {
Thread.sleep(20);
} catch (Exception ex) { }
}
}
@SuppressWarnings("serial")
class DrawElevatorOne extends JPanel{
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLUE);
g.drawRect(200,y,80,120);
}
}
}
ElevatorTwo
类(绘制绿色框的类,没有出现在我的 JFrame 中):
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class ElevatorTwo extends GUI{
int y = 400;
public void addElevatorTwo() {
DrawElevatorTwo drawE2 = new DrawElevatorTwo();
frame.getContentPane().add(drawE2);
for(int i = 0; i < 300; i++) {
y--;
drawE2.repaint();
try {
Thread.sleep(20);
} catch (Exception ex) { }
}
}
@SuppressWarnings("serial")
class DrawElevatorTwo extends JPanel{
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.GREEN);
g.drawRect(600,y,80,120);
}
}
}
最后,GUI
类(创建 frame
的地方):
import javax.swing.JFrame;
public class GUI {
JFrame frame = new JFrame();
public void createFrame(int x, int y) {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setSize(x, y);
frame.setVisible(true);
}
}
最佳答案
正如您在 previous question 中评论的那样...
Your addElevatorOne is likely going to block the EDT, meaning it I'll only paint the last position after a short delay. Consider using a Swing Timer instead to do the animation...
正如你所问的......
in the swing timer, would I call the repaint() method every time it repeats itself?
是的。 Swing Timer
将作为一个 psudo 循环,每次它滴答作响时,您将更新 y
变量,检查它是否超出您的要求并停止 Timer
如果它执行并调用 repaint
看看Concurrency in Swing和 How to use Swing Timers了解更多详情
此外,Swing 不是线程安全的,这意味着您永远不应该从 EDT 上下文之外以任何方式修改 UI。我们建议使用 Swing Timer
的原因是因为它会在 EDT 的上下文中调用已注册的 ActionListener
,从而可以安全地修改 UI
让我们重新考虑这个问题。你的代码有点复杂,很难理解。与其使用所有“多个”框架,不如集中精力制作一个知道如何移动的 Elevator
...
public class Elevator extends JPanel {
private int y = 0;
private int delta = 1;
private Color fillColor;
public Elevator(Color color, boolean goingDown) {
fillColor = color;
if (goingDown) {
y = 0;
delta = 1;
} else {
y = getPreferredSize().height - 120;
delta = -1;
}
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
y += delta;
if (y + 120 > getHeight()) {
y = getHeight() - 120;
delta *= -1;
} else if (y < 0) {
y = 0;
delta *= -1;
}
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(81, 120 * 3);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(fillColor);
g.drawRect(0, y, 80, 120);
}
}
非常简单,它是 JPanel
,具有自定义绘画来绘制实际的电梯,它设置了电梯轿厢宽度的首选尺寸,但高度是电梯轿厢的三倍(三层楼)和有自己的 Timer
来移动汽车。
构造函数允许您自定义颜色和初始移动方向
这是一个独立的工作单元。只要您不必同时运行许多电梯,就可以正常工作。如果您需要很多电梯,那么您将需要一个中央 Timer
,所有电梯都会从中收到“计时器”事件的通知,但这是另一个问题的讨论。
现在,您只需要向他们展示...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setLayout(new GridLayout(0, 2));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Elevator(Color.GREEN, true));
frame.add(new Elevator(Color.BLUE, false));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
关于java - 动画不添加到 JFrame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30904426/