我正在学习java。这是我的第一部动画。我想要一个球在按下开始按钮时连续上下移动,当按下停止按钮时它应该STOP
。我写的代码将球移动5次(向下3次,向上2次)。但面板仅显示开始和最终位置,它不显示中间位置。如何显示中间位置?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class dabble
{
private boolean z = true;
private int x=10;
private int y=10;
private JFrame frame;
private JLabel label;
private mypanel panel;
private JButton b1;
private JButton b2;
public static void main (String[] args)
{
dabble dab = new dabble();
dab.start();
}
void start()
{
frame = new JFrame();
label = new JLabel();
panel = new mypanel();
b1= new JButton("Start");
b2= new JButton("Stop");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
b1.addActionListener(new al1());
b2.addActionListener(new al2());
frame.getContentPane().add(BorderLayout.NORTH,b1);
frame.getContentPane().add(BorderLayout.SOUTH,b2);
frame.getContentPane().add(BorderLayout.CENTER,panel);
frame.getContentPane().add(BorderLayout.EAST,label);
frame.setSize(600,600);
frame.setVisible(true);
}
void go()
{
for(int i=0;i<5;i++)
{
if(z==false)
break;
//label.setText("Hi");
y=510-y;
panel.repaint();
try{
Thread.sleep(500);
//label.setText("sleep");
}catch(Exception Ex)
{
//label.setText("exp");
}
}
}
class al1 implements ActionListener{
public void actionPerformed(ActionEvent event){
go();
}
}
class al2 implements ActionListener{
public void actionPerformed(ActionEvent event){
z=false;
}
}
class mypanel extends JPanel
{
public void paintComponent ( Graphics g)
{
g.setColor(Color.white);
g.fillRect(0,0,this.getWidth(),this.getHeight());
int red = (int) (Math.random()*255);
int green = (int) (Math.random()*255);
int blue = (int) (Math.random()*255);
Color c1 = new Color(red,green,blue);
g.setColor(c1);
g.fillOval(x,y,20,20);
}
}
}
答案 0 :(得分:2)
调用repaint()
实际上并没有绘制面板 - 它只是标记它以后绘制。并且绘制总是发生在事件调度线程上,事件侦听器通知也是如此。
由于在事件调度线程(通过按钮操作侦听器)上调用go()
,因此在go()
运行时无法重新绘制面板。您只需将go()
完成后的一次重绘排队。
您可能想要做的是使用每500毫秒触发一次的javax.swing.Timer
,并且其行动是将球移动一步然后调用repaint()
。
答案 1 :(得分:0)
你执行你的循环5次(而不是无限循环)。此外,您将垂直位置从10更改为500,然后再更改为10等...如果要查看中间位置,则应考虑重新绘制中间位置以及提供y的中间值。
好的,执行以下操作可以解决您的问题,但这绝对是一个糟糕的设计:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class dabble {
private static final long ANIMATION_DURATION = 5000; // 5 seconds
private static final int REFRESH_RATE = 10;// 10 times per second
private boolean incrementing = true;
private volatile boolean z = true;
private int x = 10;
private volatile int y = 10;
private JFrame frame;
private JLabel label;
private mypanel panel;
private JButton b1;
private JButton b2;
public static void main(String[] args) {
dabble dab = new dabble();
dab.start();
}
void start() {
frame = new JFrame();
label = new JLabel();
panel = new mypanel();
b1 = new JButton("Start");
b2 = new JButton("Stop");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
b1.addActionListener(new al1());
b2.addActionListener(new al2());
frame.getContentPane().add(BorderLayout.NORTH, b1);
frame.getContentPane().add(BorderLayout.SOUTH, b2);
frame.getContentPane().add(BorderLayout.CENTER, panel);
frame.getContentPane().add(BorderLayout.EAST, label);
frame.setSize(600, 600);
frame.setVisible(true);
}
void go() {
new Animation().start();
}
class al1 implements ActionListener {
@Override
public void actionPerformed(ActionEvent event) {
go();
}
}
class al2 implements ActionListener {
@Override
public void actionPerformed(ActionEvent event) {
z = false;
}
}
class mypanel extends JPanel {
@Override
public void paintComponent(Graphics g) {
g.setColor(Color.white);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color c1 = new Color(red, green, blue);
g.setColor(c1);
g.fillOval(x, y, 20, 20);
}
}
class Animation extends Thread {
private long start;
@Override
public void run() {
start = System.currentTimeMillis();
while (true) {
if (!z) {
return;
}
double progress = (double) (System.currentTimeMillis() - start) / ANIMATION_DURATION;
System.err.println(progress);
if (incrementing) {
y = (int) (10 + 500 * progress);
} else {
y = (int) (510 - 500 * progress);
}
if (progress > 1.0) {
start = System.currentTimeMillis();
incrementing = !incrementing;
}
panel.repaint();
try {
Thread.sleep(1000 / REFRESH_RATE);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}