我试图制作一个程序,在屏幕上球会自动移动。但问题是它没有重绘();
有任何建议如何修复它?
(主要类)Main.java:
import javax.swing.*;
import java.awt.*;
public class Main extends JFrame{
static int x = 10;
public static void main(String[] args){
JFrame f = new JFrame("title");
f.setVisible(true);
f.setSize(300,250);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
sekon m = new sekon();
f.add(m);
antr t = new antr();
Thread th = new Thread(t);
th.start();
}
}
(第二课)sekon.java:
import javax.swing.*;
import java.awt.*;
public class sekon extends JPanel{
int xiu = 10;
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.RED);
g.fillOval(xiu, 10, 20, 20);
}
public void changeX(int b){
this.xiu = b;
}
}
class antr extends JPanel implements Runnable{
int xi = 10;
sekon s = new sekon();
public void run(){
xi += 1;
s.changeX(xi);
JPanel p = new JPanel();
p.repaint();
try{
Thread.sleep(5);
}catch(Exception e){}
}
}
答案 0 :(得分:2)
1)被代码行repaint()
Thread.sleep(5);
2)你的代码不起作用,因为错过了...,所有在屏幕上移动Oval
的坐标
3)对于Swing容器,Swing JComponent仅使用Swing Timer进行分析,移动,重新绘制,
确定可以使用Runnable#Thread
,但不是这样,
关于Swing Timer
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class AnimationJPanel extends JPanel {
private static final long serialVersionUID = 1L;
private int cx = 0;
private int cy = 150;
private int cw = 20;
private int ch = 20;
private int xinc = 1;
private int yinc = 1;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
AnimationJPanel panel = new AnimationJPanel();
panel.setPreferredSize(new Dimension(400, 300));
panel.animate();
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public AnimationJPanel() {
setLayout(new BorderLayout());
JLabel label = new JLabel("This is an AnimationJPanel");
label.setForeground(Color.RED);
label.setHorizontalAlignment(SwingConstants.CENTER);
add(label);
setBackground(Color.BLACK);
setForeground(Color.RED);
setOpaque(true);
}
public void animate() {
new Timer(15, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Rectangle oldCircle = new Rectangle(cx - 1, cy - 1, cw + 2, ch + 2);
cx += xinc;
cy += yinc;
if (cx >= getWidth() - cw || cx <= 0) {
xinc *= -1;
}
if (cy >= getHeight() - ch || cy <= 0) {
yinc *= -1;
}
repaint(oldCircle);
repaint(cx - 1, cy - 1, cw + 2, ch + 2);
}
}).start();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawOval(cx, cy, cw, ch);
}
}
答案 1 :(得分:1)
sekon
对象拥有的antr
实例与添加到GUI的实例不同。
答案 2 :(得分:1)
研究以下教学示例,了解如何导致重绘动画。
public static void main(String args[]) throws Exception {
new JFrame("AnimationStudy") {
int x = 0;
JPanel j = new JPanel() {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.fillOval(x, 10, 20, 20);
g.setColor(Color.BLACK);
g.drawChars(("" + x).toCharArray(), 0, ("" + x).length(), x, 10);
}
};
{
setSize(300, 100);
setLocation(300, 300);
setVisible(true);
setLayout(new BorderLayout());
add(j);
new Thread(new Runnable() {
public void run() {
int t = 250;
for (x = 10; x < t; x += 1) {
j.repaint();
try {
Thread.sleep((t - x) / 4);
} catch (Exception e) {
e.printStackTrace();
}
}
System.exit(0);
}
}).start();
}
};
}
答案 3 :(得分:0)
您的班级antr和主班级使用不同的sekon实例。您应该将main方法中创建的实例传递给antr类。