这可能是一个愚蠢的问题,但是我如何调用paintComponent呢?它根本不显示对象。它在公共类Ball中扩展了JPanel实现Runnable。
public class Balls {
public static void main(String[] args) {
new Balls();
}
public Balls() {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("Balls!");
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.add(new ballAdder());
frame.setSize(1000, 1000);
frame.setVisible(true);
}
});
}
public class ballAdder extends JPanel {
public ballAdder() {
add(new Ball(5, 5));
}
}
public class Ball extends JPanel implements Runnable {
public int x, y;
public int speedx, speedy;
public int width = 40, height = 40;
public Ball(int x, int y) {
this.x = x;
this.y = y;
new Thread(this).start();
}
public void move() {
x += speedx;
y += speedy;
if (0 > x || x > 950) {
speedx = -speedx;
}
if (0 > y || y > 950) {
speedy = -speedy;
}
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillOval(x, y, width, height);
}
public void run() {
while (true) {
move();
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}发布于 2013-06-04 09:32:26
您永远不应该自己调用paintComponent (或paint)。这是由RepaintManager完成的。
你实际遇到的问题是speedx和speedy或0,这意味着你的球永远不会移动……
另一个问题是ballAdder类使用的是FlowLayout,而您的Ball类没有提供有关它的首选大小的任何细节,这意味着Ball面板的首选大小是0x0。
审核
您的设计中存在一个重要的可伸缩性问题。除了你会发现很难添加一个以上的球到UI之外,因为布局问题…
每个Ball都有自己的线程。这意味着,您添加的球越多,运行的线程就越多。这将稳定地消耗资源,并影响应用程序的性能。
最好是提供一个Drawable对象的概念,它知道它应该在概念的容器中显示在哪里,并且可以是paintComponent中的painted。通过使用单个javax.swing.Timer,它应该更有能力支持越来越多的随机球。
首先修复
为了解决你的第一个问题,你可以这样做...
public class ballAdder extends JPanel {
public ballAdder() {
setLayout(new BorderLayout());
add(new Ball(5, 5));
}
}这个修复的问题是,你只能在容器上有一个Ball,因为它想要占用最大的可用空间。
您可能需要通读一下Using Layout Managers以了解更多详细信息
A (可能)更好的解决方案
一个(可能的)更好的解决方案是使用单个JPanel作为“球坑”,它维护了对球列表的引用。
然后使用BallPitPane的paintComponent方法绘制所有球(在球列表中)。
通过使用单个javax.swing.Timer,您可以迭代球列表并更新那里的位置(在BallPitPane的上下文中
我的意思是,这比尝试使用布局管理器或编写自己的布局管理器更容易…

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Bounce {
public static void main(String[] args) {
new Bounce();
}
public Bounce() {
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 BallPitPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class BallPitPane extends JPanel {
private List<Ball> balls;
private Random rand;
public BallPitPane() {
rand = new Random(System.currentTimeMillis());
balls = new ArrayList<>(25);
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (balls.isEmpty()) {
balls.add(new Ball(BallPitPane.this));
}
if (rand.nextBoolean()) {
balls.add(new Ball(BallPitPane.this));
}
for (Ball ball : balls) {
ball.move();
}
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (Ball ball : balls) {
ball.paint(g2d);
}
g2d.dispose();
}
}
protected static int random(int min, int max) {
return (int)Math.round(Math.random() * (max - min)) + min;
}
public static class Ball {
public static final int WIDTH = 10;
public static final int HEIGHT = 10;
private int x;
private int y;
private int deltaX;
private int deltaY;
private Color color;
private BallPitPane parent;
public Ball(BallPitPane parent) {
this.parent = parent;
x = parent.getWidth() / 2;
y = parent.getHeight() / 2;
deltaX = random(-4, 4);
deltaY = random(-4, 4);
color = new Color(random(0, 255), random(0, 255), random(0, 255));
}
public void move() {
x += deltaX;
y += deltaY;
if (x + WIDTH > parent.getWidth()) {
x = parent.getWidth() - WIDTH;
deltaX *= -1;
} else if (x < 0) {
x = 0;
deltaX *= -1;
}
if (y + HEIGHT > parent.getHeight()) {
y = parent.getHeight() - HEIGHT;
deltaY *= -1;
} else if (y < 0) {
y = 0;
deltaY *= -1;
}
}
public Color getColor() {
return color;
}
public void paint(Graphics2D g2d) {
g2d.setColor(getColor());
g2d.fillOval(x, y, WIDTH, HEIGHT);
g2d.setColor(Color.BLACK);
g2d.drawOval(x, y, WIDTH, HEIGHT);
}
}
}https://stackoverflow.com/questions/16908418
复制相似问题