Home > Software engineering >  Why I can't add more than one Object to the JPanel?
Why I can't add more than one Object to the JPanel?

Time:05-26

When I add to the GameScreen more than one Object of class Duck only one appears on the screen. When I add Duck outside constructor in GameScreen class I have many Object of Duck but then the mouseClicked method doesn't work on Duck.

 public class GameScreen extends JPanel{
        public GameScreen(){
    
            JPanel bottompanel = new JPanel();
            Duck duck1  = new Duck("/red-duck.png", 200, 70, 70, 40);
            Duck duck2  = new Duck("/blue-duck.png", 50, 70, 70, 5);
          
        this.setLayout(new BorderLayout());


        bottompanel.add(labelTime);
        this.add(bottompanel, BorderLayout.SOUTH);

       this.add(duck1);
       this.add(duck2);

        new Thread(
                () -> {
                    while (!Thread.currentThread().isInterrupted()) {
                        labelTime.setText(String.valueOf(start));
                        repaint();
                    }
                }
        ).start();

/////////////////////////////////////////////////////////////////////////

public class Duck extends JPanel implements ImageObserver, MouseListener {
    private BufferedImage image;
    private String pathname;
    private int distance;
    private int speed;
    public int x;
    private int y;
    private int width;
    private int hight;
    private int lives;



    public Duck(String pathname, int y, int width, int hight, int speed) {
        super();
        this.pathname = pathname;
        this.speed = speed;
        this.distance =  1   (int)(Math.random()*speed);
        this.x = 0;
        this.y = y;
        this.width = width;
        this.hight = hight;
        this.lives = duckColor();
        this.addMouseListener(this);
        System.out.println("make duck"  lives);
        timer.start();



        File imageFile = new File(pathname);
        try {
            image = ImageIO.read(imageFile);
        } catch (IOException e) {
            System.err.println("Blad odczytu obrazka");
            e.printStackTrace();
        }

    }

    ActionListener al=new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
            x  = distance;
    
        }
    };
    Timer timer=new Timer(100,al);
public void paintComponent(Graphics g) {
      // super.paintComponent(g);
       Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(image, x, y, width, hight, this);
    }

@Override
public void mouseClicked(MouseEvent e) {
        lives--; 
}

CodePudding user response:

Take a look at enter image description here

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    BufferedImage img = ImageIO.read(getClass().getResource("/images/Duck.png"));
                    List<Duck> ducks = new ArrayList<>();
                    ducks.add(new Duck(img));
                    ducks.add(new Duck(img));

                    JFrame frame = new JFrame();
                    frame.add(new GamePane(ducks));
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    public class Duck {
        private BufferedImage image;

        private int x;
        private int y;

        private int xDelta = 0;
        private int yDelta = 0;

        public Duck(BufferedImage image) {
            this.image = image;
        }

        public BufferedImage getImage() {
            return image;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        public void setLocation(int x, int y) {
            setX(x);
            setY(y);
        }

        public void setX(int x) {
            this.x = x;
        }

        public void setY(int y) {
            this.y = y;
        }

        public int getWidth() {
            return image == null ? 0 : image.getWidth();
        }

        public int getHeight() {
            return image == null ? 0 : image.getHeight();
        }

        public void setDelta(int x, int y) {
            xDelta = x;
            yDelta = y;
        }

        public int getXDelta() {
            return xDelta;
        }

        public int getYDelta() {
            return yDelta;
        }

        public void move(Rectangle bounds) {
            int xDelta = getXDelta();
            int yDelta = getYDelta();
            int x = getX()   xDelta;
            int y = getY()   yDelta;

            if (x < bounds.x) {
                x = bounds.x;
                xDelta *= -1;
            } else if (x   getWidth() >= bounds.x   bounds.width) {
                x = (bounds.x   bounds.width) - getWidth();
                xDelta *= -1;
            }

            if (y < bounds.y) {
                y = bounds.y;
                yDelta *= -1;
            } else if (y   getWidth() >= bounds.y   bounds.height) {
                y = (bounds.y   bounds.height) - getHeight();
                yDelta *= -1;
            }
            setDelta(xDelta, yDelta);
            setLocation(x, y);
        }

        public void paint(Graphics2D g2d, ImageObserver observer) {
            g2d.drawImage(getImage(), getX(), getY(), observer);
        }
    }

    public class GamePane extends JPanel {
        private List<Duck> ducks;

        public GamePane(List<Duck> ducks) {
            this.ducks = ducks;

            Random rnd = new Random();

            for (Duck duck : ducks) {
                int width = 400 - duck.getWidth();
                int height = 400 - duck.getHeight();

                int x = rnd.nextInt(width);
                int y = rnd.nextInt(height);

                int xDelta = rnd.nextBoolean() ? 1 : -1;
                int yDelta = rnd.nextBoolean() ? 1 : -1;

                duck.setLocation(x, y);
                duck.setDelta(xDelta, yDelta);
            }

            Timer timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Rectangle bounds = new Rectangle(getSize());
                    for (Duck duck : ducks) {
                        duck.move(bounds);
                    }
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            for (Duck duck : ducks) {
                Graphics2D g2d = (Graphics2D) g.create();
                duck.paint(g2d, this);
                g2d.dispose();
            }
        }
    }
}

From this, you can start adding more entities as needed, for example, I can modify the Main method to include LOTs of ducks...

BufferedImage img = ImageIO.read(getClass().getResource("/images/Duck.png"));
List<Duck> ducks = new ArrayList<>(100);
for (int index = 0; index < 100; index  ) {
    ducks.add(new Duck(img));
}

This is obviously and overly simplified example intended only as a demonstration of core concept, you'll need to do more research into basic game development and 2D graphics.

  • Related