我是java GUI的新手,我正在尝试学习它。我想自动在屏幕上移动一个圆圈(即不要按任何键或做任何其他动作)。我找到了一种通过做一些动作来移动它的方法,但这不是我需要的。请有人告诉我最简单的方法吗?
我想删除以下代码中的动作侦听器,以便圆圈自动移动:
public class MyFirstGraphics extends JFrame {
int x = 100;
int y = 100;
MyFirstGraphics() {
super("Circle");
setSize(800, 800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getContentPane().setBackground(Color.pink);
JButton f = new JButton("circle");
f.addActionListener(new re());
add(f, BorderLayout.NORTH);
}
private class re implements ActionListener {
public void actionPerformed(ActionEvent e) {
for (int i = 1; i < 50; i++) {
x++;
y++;
repaint();
}
}
}
public void paint(Graphics g) {
super.paint(g);
g.drawOval(x, y, 100, 100);
}
public static void main(String[] args) {
MyFirstGraphics l = new MyFirstGraphics();
l.setVisible(true);
}
}
答案 0 :(得分:5)
让我们从动画是随时间变化的幻觉开始。此外,Swing是一个单线程环境。您不能“阻止”Swing线程(也就是事件调度线程)并让它绘制更新,您需要一些方法来定期更新更新,以便您可以应用更改,然后重新绘制更改... < / p>
所以你的第一个问题出在actionPerformed
方法......
for (int i = 1; i < 50; i++) {
x++;
y++;
repaint();
}
基本上,唯一可以画的是150x150的球,其间没有任何其他东西可以画。
相反,您需要将其更改为更像......
public void actionPerformed(ActionEvent e) {
if (x < 150 && y < 150) {
x++;
y++;
} else {
((Timer)e.getSource()).stop();
}
repaint();
}
看看:
了解更多详情
一个基本的“弹性”球示例
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
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 BounceyDot {
public static void main(String[] args) {
new BounceyDot();
}
public BounceyDot() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private int x = 0;
private int y = 100;
private int radius = 20;
private int xDelta = 2;
public TestPane() {
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
x += xDelta;
if (x + (radius * 2) > getWidth()) {
x = getWidth() - (radius * 2);
xDelta *= -1;
} else if (x < 0) {
x = 0;
xDelta *= -1;
}
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.fillOval(x, y - radius, radius * 2, radius * 2);
}
}
}
答案 1 :(得分:2)
要为该代码设置动画,请使用基于Swing的Timer
和re
ActionListener
作为构造函数中的一个参数(另一个参数是延迟)。
有关详细信息和工作示例,请参阅How to Use Swing Timers。