我有一个程序可以在Jpanel中设置动画。我有两个按钮Stop and Go。停止球停止移动并且移动意味着球移动。在我的球类中,我有一个布尔变量,如果它是真的,则球移动,如果是假,则球不移动。因此,当我创建框架并将球类放在面板中时,我想在我的主类中,我可以使用按钮将变量更改为false或true,具体取决于按下按钮。
public class BallTask extends JPanel implements ActionListener{
public static boolean run = false;
public BallTask(){
this.setPreferredSize(new Dimension(width, height));
Thread gameThread = new Thread() {
public void run() {
while (run) {
.... working code
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame window = new JFrame();
window.setLayout(new BorderLayout());
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.add(new BallTask());
JPanel buttons = new JPanel();
JButton stop = new JButton("STOP");
stop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
run = false;
}
});
JButton go = new JButton("GO");
go.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
run = true;
}
});
buttons.add(go);
buttons.add(stop);
window.add(buttons,BorderLayout.SOUTH);
window.pack();
window.setVisible(true);
}
});
我对代码的问题是按钮实际上并没有改变BallTask类中的布尔值。有什么想法吗?
答案 0 :(得分:2)
使用javax.swing.Timer
。你的while循环将阻止EDT不允许调度按钮事件。
使用计时器,您可以使用它的方法stop
和start
来启动和停止计时器。您可以看到示例here
这是一个使用Timer
代码的可运行示例。上面链接中的代码使用Ball
对象更干净。我只是把这个快速地扔到了一起
import java.awt.BorderLayout;
import java.awt.Dimension;
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.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class BallTask {
public static boolean run = false;
private Timer timer;
private BallPanel ballPanel = new BallPanel();
public BallTask() {
timer = new Timer(30, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (ballPanel.x < 0 || ballPanel.x > ballPanel.getWidth()) {
ballPanel.dx = -ballPanel.dx;
}
if (ballPanel.y < 0 || ballPanel.y > ballPanel.getHeight()) {
ballPanel.dy = -ballPanel.dy;
}
// Adjust ball position
ballPanel.x += ballPanel.dx;
ballPanel.y += ballPanel.dy;
ballPanel.repaint();
}
});
JPanel buttons = new JPanel();
JButton stop = new JButton("STOP");
buttons.add(stop);
stop.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.stop();
}
});
JButton go = new JButton("GO");
buttons.add(go);
go.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(ballPanel);
mainPanel.add(buttons, BorderLayout.SOUTH);
JFrame window = new JFrame();
window.add(mainPanel);
window.pack();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setLocationRelativeTo(null);
window.setVisible(true);
}
private class BallPanel extends JPanel {
private int x;
private int y;
int dx = 4; // Increment on ball's x-coordinate
int dy = 4; // Increment on ball's y-coordinate
int radius = 15; // Ball radius
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillOval(x, y, 30, 30);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 300);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new BallTask();
}
});
}
}