我是java swing的新手。在尝试使用图形时,我会遇到这种情况。 我无法在网络上找到合适的解决方案。所以我想在这里发帖。
所以现在让我们来解决我的问题。首先,我将解释我想做什么。然后我将解释我的问题。
我试图让两个球在JFrame中同时向不同方向移动。 (基本上我想做类似连锁反应的游戏,当你点击一个装满的盒子时,球会同时向不同的方向移动)。
这里我创建两个(截至目前)两个球的JPanels,我试图同时在JFrame上移动。
这是我试过的代码,
public class chainGraphics扩展了JPanel实现的Runnable {
int oldX,oldY,newX,newY;
int changeX,changeY;
Container myPane;
public chainGraphics(int oldX,int oldY,int newX,int newY,Container myPane) {
// TODO Auto-generated constructor stub
this.myPane=myPane;
this.oldX=oldX;
this.oldY=oldY;
this.newX=newX;
this.newY=newY;
myPane.add(this);
}
public void paintComponent(Graphics g) {
//super.paintComponent(g);
System.out.println("hj");
g.drawOval(changeX,changeY, 40, 40);
}
@Override
public void run() {
System.out.println("hii");
changeX =oldX;
changeY = oldY;
if((newY-oldY)==0){
if(oldX<newX){
for(int i=oldX;i<newX;i++){
System.out.println("hii123");
changeX = i;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
repaint();
}
}
else {
for(int i=oldX;i>newX;i--){
changeX=i;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
repaint();
}
}
}
if((newX-oldX)==0){
if(oldY<newY){
for(int i=oldY;i<newY;i++){
changeY=i;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
repaint();
}
}
else {
for(int i=oldY;i>newY;i--){
changeY=i;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
repaint();
}
}
}
}
public static void main(String[] args) {
JFrame gui = new JFrame();
gui.setTitle("Chain Reaction ;-) ");
gui.setSize(650,650);
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setLocationRelativeTo(null);
gui.setVisible(true);
Container Pane = gui.getContentPane();
chainGraphics g = new chainGraphics(100,200,300,200,Pane);
chainGraphics g1 = new chainGraphics(200,100,200,300,Pane);
Thread t1 = new Thread(g);
t1.start();
Thread t2 = new Thread(g1);
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
在这里我看不到两个球同时移动。我猜有一个问题。 我能够看到球只沿y方向移动。 (但我希望两个球同时移动,因为我创造了两个线程)
我还注意到我先创建g1对象然后再创建g对象, 然后球只沿x方向移动。
我认为Jframe一次只能处理1个JPanel。 (我将JPanel添加到Frame彻底的构造函数中)。因此,最后将JPanel添加到框架中,它允许对其进行处理。是这样吗 ? 如果我现在该怎么办。我的要求是我想在不同方向同时移动球。 感谢。
答案 0 :(得分:3)
“不,我试图用两个线程画两个球”
不要尝试将面板的两个实例添加到容器中。只需使用Ball
个对象的数据结构(我更喜欢List),然后在paintComponent
方法中循环它们。每个球都可以使用drawBall(Graphics g)
方法,您可以使用paintComponent
方法调用该方法,并将Graphics
上下文
使用Swing Timer
并忘记线程。 Thread.sleep
不是你在Swing的朋友。请参阅How to use Swing Timers
在计时器中,只需更改每个Ball
对象的位置/轨迹,然后调用repaint()
。您可以在Ball
课程中使用可改变方向的方法。
在Event Dispatch Thread上运行Swing应用程序。您可以将main
方法代码包装在SwingUtilities.invokeLater..
中。请参阅Initial Threads
这是一个例子
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
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.SwingUtilities;
import javax.swing.Timer;
public class MoveBalls extends JPanel {
private static final int D_W = 500;
private static final int D_H = 300;
private List<Ball> balls;
public MoveBalls() {
Random rand = new Random();
balls = new ArrayList<>();
for (int i = 0; i < 10; i++) {
int randX = rand.nextInt(D_W);
int randY = rand.nextInt(D_H);
balls.add(new Ball(randX, randY));
}
Timer timer = new Timer(15, new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (Ball ball : balls) {
ball.animate();
}
repaint();
}
});
timer.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Ball ball : balls) {
ball.drawBall(g);
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(D_W, D_H);
}
public class Ball {
int x = 0;
int y = 0; // Current ball position
int dx = 4; // Increment on ball's x-coordinate
int dy = 4; // Increment on ball's y-coordinate
int radius = 15; // Ball radius
public Ball(int x, int y) {
this.x = x;
this.y = y;
}
Color color = new Color((int) (Math.random() * 256),
(int) (Math.random() * 256), (int) (Math.random() * 256));
public void drawBall(Graphics g) {
g.setColor(color);
g.fillOval(x - radius, y - radius,
radius * 2, radius * 2);
}
public void animate() {
if (x < 0 || x > getWidth()) {
dx = -dx;
}
if (y < 0 || y > getHeight()) {
dy = -dy;
}
// Adjust ball position
x += dx;
y += dy;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.add(new MoveBalls());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}