在一个JFrame中同时处理两个JPanel [英] working on two JPanels simultaneously in a single JFrame

查看:124
本文介绍了在一个JFrame中同时处理两个JPanel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Java swing的新手。而当试图与图形我卡住了这一点。
我无法在网上找到合适的解决方案。所以我想在这里发帖。



现在让我们来解决我的问题。首先,我会解释我在做什么。然后我会解释我的问题。



我试图让两个球在JFrame中同时向不同的方向移动。 (基本上我认为就像连锁反应游戏一样,当你点击一个填充框时,球会同时向不同的方向移动)。

这里我创建两个(截至目前为止)两个球的JPanels,我试图在JFrame上同时移动。



这里是我试过的代码,

public class chainGraphics extends JPanel implements Runnable {

  int oldX,oldY,newX,newY; 
int changeX,changeY;
容器myPane;
public chainGraphics(int oldX,int oldY,int newX,int newY,Container myPane){
// TODO自动生成的构造函数存根
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; ((newY-oldY)== 0){
if(oldX< newX){
for(int i = oldX; i< newX; i ++){

b $ b System.out.println(hii123);
changeX = i;
尝试{
Thread.sleep(10);
} catch(InterruptedException e){

e.printStackTrace();
}

repaint();


else {
for(int i = oldX; i> newX; i - ){
changeX = i;
尝试{
Thread.sleep(10);
} catch(InterruptedException e){
e.printStackTrace();
}
repaint(); ((newX-oldX)== 0){
if(oldY



for(int i = oldY; i changeY = i;
尝试{
Thread.sleep(10);
} catch(InterruptedException e){
// TODO自动生成的catch块
e.printStackTrace();
}
repaint();


else {
for(int i = oldY; i> newY; i - ){
changeY = i;
尝试{
Thread.sleep(10);
} catch(InterruptedException e){
// TODO自动生成的catch块
e.printStackTrace();
}
repaint();




$ b public static void main(String [] args){

JFrame gui =新的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);
线程t1 =新线程(g);
t1.start();
线程t2 =新线程(g1);
t2.start();


尝试{
t1.join();
t2.join();
} catch(InterruptedException e){
e.printStackTrace();
}

}

}



在这里,我看不到两个球同时移动。我猜想有一个问题。
我只能看到球沿y方向移动。 (但我希望两个球同时移动,因为我创建了两个线程)

我还注意到如果我先创建g1对象然后再创建g对象
那么球只会沿着x方向移动。

我认为Jframe只允许在一个JPanel上工作。 (并且我将JPanel添加到Frame彻底构造函数中)。所以JPanel最后添加到框架中,它允许在它上面工作。是这样吗 ?
如果是,我现在应该做什么。我的要求是我想在不同的方向同时移动球。
Thanks。

解决方案


不,我想用两个线程绘制两个球





  1. 不要尝试将面板的两个实例添加到容器中。只需使用 Ball 对象的数据结构(我喜欢列表),并在 paintComponent 方法中遍历它们。每个球都可以有一个 drawBall(Graphics g)方法,你可以在 paintComponent 方法中调用,传入 Graphics context


  2. 使用Swing Timer 并忘记线程。 Thread.sleep 不是Swing中的朋友。请参阅如何使用Swing Timers Ball 对象的位置/轨迹,并调用重绘()。您可以在 Ball 类中添加方法,以改变方向。

  3. 调度线程。你可以通过将 main 方法代码包装在 SwingUtilities.invokeLater .. 中来实现。请参阅初始主题







以下是一个例子

  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;
导入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;

私人列表< Ball>球;

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));


定时器定时器=新定时器(15,新的ActionListener(){
public void actionPerformed(ActionEvent e){
for(Ball ball:balls){
ball.animate();
}
repaint();
}
});
timer.start();


@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
(球球:球){
ball.drawBall(g);


$ b @Override
public Dimension getPreferredSize(){
return new Dimension(D_W,D_H);
}

public class Ball {

int x = 0;
int y = 0; //当前球位置
int dx = 4; //增加球的x坐标
int dy = 4; //增加球的y坐标
int radius = 15; //球半径

public Ball(int x,int y){
this.x = x;
this.y = y; (Math.random()* 256),
(int)(Math.random()* 256),(int)(Math .random()* 256));

public void drawBall(Graphics g){
g.setColor(color);
g.fillOval(x - 半径,y - 半径,
半径* 2,半径* 2);
}

public void animate(){
if(x <0 || x> getWidth()){
dx = -dx;
}
if(y< 0 || y> getHeight()){
dy = -dy;
}
//调整球位置
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);
}
});
}
}


I m a newbie to java swing . And when trying with graphics i got stuck with this. I could'nt find a proper solution in web . So i thought of posting here .

so now lets come to my problem . First i will explain what i m trying to do . And then i will explain about my problem.

I m trying to make two balls move in different directions simultaneously in a JFrame . (Basically i thought of doing like chain Reaction game in which when you click on a filled box, the balls will move simultaneously in different directions ) .

Here i m creating two (as of now) JPanels for two balls which i m trying to move on a JFrame SIMULTANEOUSLY .

here is the code which i tried out ,

public class chainGraphics extends JPanel implements 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();
    }

}

}

Here i couldnt see two balls moving simultaneously . There is a problem i guess. i could able to see ball moving along y direction only . (but i want both ball to move simutaneously, since i create two threads)

And i also noticed if i create g1 object first and then g object , then the ball moves along x direction only .

I think the Jframe allows to work on 1 JPanel only at a time . (And i am adding the JPanel to Frame thorough Constructor ) . so which ever JPanel is added lastly to frame ,it allows to work on it . is it so ? IF yes what should i do now .My requirement is i want to move balls simultaneously in different Directions. Thanks.

解决方案

"No i am trying to draw two balls using two threads"

  1. Don't try and add two instances of your panel to a container. Just Use a data structure (I prefer List) of Ball objects and loop through them in the paintComponent method. Each ball can have a drawBall(Graphics g) method that you can call in the paintComponent method, passing to it the Graphics context

  2. Use a Swing Timer and forget about the threading. Thread.sleep isn't your friend in Swing. See How to use Swing Timers

  3. In the Timer, just change the locations/trajectory of locations of each Ball object and call repaint(). You can have methods in your Ball class that will change direction.

  4. Run Swing apps on the Event Dispatch Thread. You can do so by wrapping your main method code in a SwingUtilities.invokeLater... See Initial Threads


Here's an example

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);
            }
        });
    }
}

这篇关于在一个JFrame中同时处理两个JPanel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆