如何在两个不同类的JF​​rame中将两个圆圈移动到一起

时间:2015-03-04 16:13:07

标签: java swing java-2d

我试图在一帧上显示两个圆圈一起移动     通过两个不同的类。但是,只有一个显示移动,即使值" x"在class1中不断变化,paintComponent()只取值" x1"并显示从class child2移动的圆圈。

如果为两个类分配了两个单独的帧,它们的工作完全正常。 这是我的代码

import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Test13
{
    public static void main(String[] args)
    {
        child1 c1 = new child1();
        child2 c2 = new child2();
        JFrame f1 = new JFrame("Frame Test1");
        f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//passing a single JFrame to both methods as parameters    
        c1.cfunc1(f1);   
        c2.cfunc2(f1);   // but this line always hides the upper one
        f1.setSize(1000,700);
        f1.setVisible(true);
    }

}

class child1 extends JPanel implements ActionListener
{
    int x,y;
    int delay1;
    Timer timer1; //timer for 1st class constructor

    child1()
    {
        x=1;
        y=100;
        timer1 = new Timer(50,this);
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        if(x <= 500)
        {
            x += 1;
            y = 100;
            repaint();
        }
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.fillOval(x, y, 10, 10);
    }

    void cfunc1(JFrame f1)//passing JFrame as parameter 
    {
        child1 c1 = new child1();
        f1.add(c1);
        c1.timer1.start(); //timer started at the end of class1
    }
}  

class child2 extends JPanel implements ActionListener
{
    int x1,y1;
    int delay2;
    Timer timer2;

    child2()
    {
        x1 = 500;
        y1 = 100;
        timer2 = new Timer(50,this);//timer for 2nd class constructor
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        if(x1 <= 500)
        {
            x1 -= 1;
            y1 = 100;
            repaint();
        }
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.fillOval(x1, y1, 10, 10);
    }

    void cfunc2(JFrame f1)//passing JFrame as parameter
    {
        child2 c2 = new child2();
        f1.add(c2);
        c2.timer2.start();//timer started for 2nd class
    }
} 

2 个答案:

答案 0 :(得分:4)

当两个组件添加到BorderLayout的单个约束(JFrame的默认布局)时,只显示一个。

执行此操作的典型方法不是在JComponent(如JPanel)中设计自定义绘画,而是将它们设为可以paint(Graphics)或{{1当被要求这样做时。

然后扩展一个draw(Graphics),它迭代一个可绘制组件的列表并绘制每个组件。

答案 1 :(得分:2)

不要为每个对象创建单独的类(child1,child2)。如果你想要50件物品怎么办?而是创建一个接受允许您自定义对象的参数的类。

此示例显示了您的方式:

  1. 创建一个通用的Ball类。
  2. 使用Swing Timer进行球的动画
  3. 通过调用每个Ball的draw(...)方法创建一个自定义绘画的面板。
  4. 以下是代码:

    import java.awt.*;
    import java.awt.event.*;
    import java.awt.image.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.Timer;
    
    public class BallAnimation4
    {
        private static void createAndShowUI()
        {
            BallPanel panel = new BallPanel();
    
            JFrame frame = new JFrame("BallAnimation4");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add( panel );
            frame.setSize(800, 600);
            frame.setLocationRelativeTo( null );
            //frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
            frame.setVisible( true );
    
            panel.addBalls(5);
            panel.startAnimation();
        }
    
        public static void main(String[] args)
        {
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    createAndShowUI();
                }
            });
        }
    }
    
    class BallPanel extends JPanel implements ActionListener
    {
        private ArrayList<Ball> balls = new ArrayList<Ball>();
    
        public BallPanel()
        {
            setLayout( null );
            setBackground( Color.BLACK );
        }
    
        public void addBalls(int ballCount)
        {
            Random random = new Random();
    
            for (int i = 0; i < ballCount; i++)
            {
                Ball ball = new Ball();
                ball.setRandomColor(true);
                ball.setLocation(random.nextInt(getWidth()), random.nextInt(getHeight()));
                ball.setMoveRate(32, 32, 1, 1, true);
    //          ball.setMoveRate(16, 16, 1, 1, true);
                ball.setSize(32, 32);
                balls.add( ball );
            }
        }
    
        @Override
        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
    
            for (Ball ball: balls)
            {
                ball.draw(g);
            }
        }
    
        public void startAnimation()
        {
            Timer timer = new Timer(75, this);
            timer.start();
        }
    
        public void actionPerformed(ActionEvent e)
        {
            move();
            repaint();
        }
    
        private void move()
        {
            for (Ball ball : balls)
            {
                ball.move(this);
            }
        }
    
    
        class Ball
        {
            public Color color = Color.BLACK;
    
            public int x = 0;
            public int y = 0;
            public int width  = 1;
            public int height = 1;
    
            private int moveX = 1;
            private int moveY = 1;
            private int directionX = 1;
            private int directionY = 1;
            private int xScale = moveX;
            private int yScale = moveY;
    
            private boolean randomMove = false;
            private boolean randomColor = false;
            private Random myRand = null;
    
            public Ball()
            {
                myRand = new Random();
                setRandomColor(randomColor);
            }
    
            public void move(JPanel parent)
            {
                int iRight = parent.getSize().width;
                int iBottom = parent.getSize().height;
    
                x += 5 + (xScale * directionX);
                y += 5 + (yScale * directionY);
    
                if (x <= 0)
                {
                    x = 0;
                    directionX *= (-1);
                    xScale = randomMove ? myRand.nextInt(moveX) : moveX;
                    if (randomColor) setRandomColor(randomColor);
                }
    
                if (x >= iRight - width)
                {
                    x = iRight - width;
                    directionX *= (-1);
                    xScale = randomMove ? myRand.nextInt(moveX) : moveX;
                    if (randomColor) setRandomColor(randomColor);
                }
    
                if (y <= 0)
                {
                    y = 0;
                    directionY *= (-1);
                    yScale = randomMove ? myRand.nextInt(moveY) : moveY;
                    if (randomColor) setRandomColor(randomColor);
                }
    
                if (y >= iBottom - height)
                {
                    y = iBottom - height;
                    directionY *= (-1);
                    yScale = randomMove ? myRand.nextInt(moveY) : moveY;
                    if (randomColor) setRandomColor(randomColor);
                }
            }
    
            public void draw(Graphics g)
            {
                g.setColor(color);
                g.fillOval(x, y, width, height);
            }
    
            public void setColor(Color c)
            {
                color = c;
            }
    
            public void setLocation(int x, int y)
            {
                this.x = x;
                this.y = y;
            }
    
            public void setMoveRate(int xMove, int yMove, int xDir, int yDir, boolean randMove)
            {
                this.moveX = xMove;
                this.moveY = yMove;
                directionX  = xDir;
                directionY  = yDir;
                randomMove  = randMove;
            }
    
            public void setRandomColor(boolean randomColor)
            {
                this.randomColor = randomColor;
    
                switch (myRand.nextInt(3))
                {
                    case 0:  color = Color.BLUE;
                             break;
                    case 1:  color = Color.GREEN;
                             break;
                    case 2:  color = Color.RED;
                             break;
                    default: color = Color.BLACK;
                             break;
                }
            }
    
            public void setSize(int width, int height)
            {
                this.width  = width;
                this.height = height;
            }
        }
    }
    

    通常你不会使这些类成为静态的。