簡體   English   中英

如何在JFrame中將來自兩個不同類的兩個圓一起移動

[英]How to move two circles together in a JFrame from two different classes

我試圖通過兩個不同的類顯示兩個圓圈在同一幀上一起移動。 但是,即使在child1類中“ x”的值不斷變化,一次也僅顯示一個移動,而paintComponent()僅取值“ x1”並顯示了從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
    }
} 

將兩個組件添加到BorderLayoutJFrame的默認布局)的單個約束中時,僅顯示一個。

實現此目的的典型方法不是在JComponent設計自定義繪畫(例如JPanel ),而是將它們作為簡單的類,可以在需要時paint(Graphics)draw(Graphics)

然后,擴展單個JComponent ,以迭代可繪制組件的列表並繪制每個組件。

不要為每個對象創建單獨的類(child1,child2)。 如果要50個對象怎么辦? 而是創建一個接受參數的類,該參數允許您自定義對象。

本示例說明了如何:

  1. 創建一個通用的Ball類。
  2. 使用Swing Timer對球進行動畫處理
  3. 通過調用每個Ball的draw(...)方法來創建一個進行自定義繪畫的面板。

這是代碼:

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

通常,您不會將類設為靜態。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM