我仍在学习 GUI,但在理解线程方面仍然遇到一些困难:/
我正在制作这个 GUI,其中有 2 个圆圈,一大圈 (100x100) 和一小圈 (50x50)。小圆圈将到达大圆圈的边缘,在 0.5 秒内,小圆圈将到达中心,当用户必须单击时。每当用户在圆圈位于中间时单击时,用户就会得分。我遇到的唯一麻烦是圆圈没有移动,因为我怀疑它与我的线程有关,因此我使用线程的原因是为了了解如何使用它们。
图形用户界面
public class gui extends JPanel implements MouseListener,
Runnable {
Thread t = new Thread();
int score = 0;
int rnd;
static final int smallcircleposx = 75;
static final int smallcircleposy = 75;
int circleposx = 75;
int circleposy = 75;
int mousex, mousey;
Random random = new Random();
public gui() {
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillOval(50, 50, 100, 100);
g.setColor(Color.RED);
g.fillOval(circleposx, circleposy, 50, 50);
}
// THREAD FOR MOVING THE CIRCLE
public void run() {
rnd = random.nextInt(999);
if (rnd % 5 == 0) {
circleposx = circleposx + 25;
} else if (rnd % 4 == 0) {
circleposx = circleposx - 25;
} else if (rnd % 3 == 0) {
circleposy = circleposy + 25;
} else {
circleposy = circleposy - 25;
}
try {
Thread.sleep(500);
circleposx = smallcircleposx;
circleposy = smallcircleposy;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void mouseClicked(MouseEvent m) {
if (circleposx == smallcircleposx && circleposy == smallcircleposy) {
score++;
}
}
主要内容
public class main {
public static void main(String[] args) {
JFrame frame = new JFrame("Circle enlarger");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400,400);
frame.setVisible(true);
gui co = new gui();
frame.add(co);
frame.addMouseListener(co);
Thread x = new Thread(new gui());
x.start();
}
}
我知道我没有使用所有的 mouselistener
方法。
最佳答案
需要记住的一些要点:
如果您不重写所有方法,请使用
MouseAdaptor
而不是MouseListener
。不要直接在顶级容器(例如
JFrame
、JApplet
)上绘制,而是使用JPanel
不要使用有时会挂起整个 swing 应用程序的
Thread.sleep()
,而是尝试使用 Swing Timer最适合 Swing 应用。不要忘记在重写的
paintComponent()
方法中调用super.paintComponent()
。添加完所有组件后最后调用
frame.setVisible(true)
。使用
frame.pack()
而不是frame.setSize()
,根据组件的首选尺寸来适合组件。重写
getPreferredSize()
以设置自定义绘画时JPanel
的首选大小。使用SwingUtilities.invokeLater()或EventQueue.invokeLater()确保EDT已正确初始化。
了解更多
值得一读Lesson: Performing Custom Painting
<小时/>示例代码:(根据您的自定义绘画进行更改)
private Timer timer;
...
// 500 Milli-seconds
timer = new javax.swing.Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// change the coordinate
panel.repaint();
if (condition) {
timer.stop(); // you can stop the timer anytime
}
}
});
timer.setRepeats(true); // you can turn-off the repeatation
timer.start();
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// Initialize the UI
}
});
}
class MyJPanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
...
}
@Override
public Dimension getPreferredSize() {
return new Dimension(..., ...);
}
}
关于java - 如何制作一个动画圈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22366084/