Java Swing: how to react to clicking a custom JComponent?

81 Views Asked by At

I'm trying to make a game with ducks, the ducks are moving on the screen and I can't get a mouse click on them. I'm obviously doing something wrong because despite setting a MouseListener, its methods are not called. This is my code, I omitted getters and the DuckGame class, which is only generating ducks.

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class DuckGameScreen extends JPanel {
    private int initialDuckNum = 7;
    private final int INTERVAL = 25;
    private final int INTERVAL_BTWN_DUCKS = 1000;
    private Timer duckTimer;
    private int ducksStarted = 0;
    private DuckGame duckGame;


    public DuckGameScreen() {
        setBackground(Color.cyan);
        askAboutDifficulty();
        startTimer();
        startGame();
        startDifficultyIncrease();
    }

    private void startGame() {
        duckGame = new DuckGame(initialDuckNum);
        startDucks();
        addDuckListeners();
    }

    private void addDuckListeners() {
        for (Duck duck : duckGame.getDucks()) {
            duck.addMouseListener(new MouseListener() {
                @Override
                public void mouseClicked(MouseEvent e) {}

                @Override
                public void mousePressed(MouseEvent e) {
                    System.out.println("Duck clicked");}

                @Override
                public void mouseReleased(MouseEvent e) {}
                @Override
                public void mouseEntered(MouseEvent e) {}
                @Override
                public void mouseExited(MouseEvent e) {}
            });
        }
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        drawDucks(g);
        Toolkit.getDefaultToolkit().sync();
    }

    private void animateDuck(Duck duck) {
        new Thread() {
            @Override
            public void run() {
                super.run();
                while (!duck.isDuckStopped()) {
                    try {
                        Thread.sleep(INTERVAL);
                        duck.move();
                        if (duck.getX() - duck.getWidth() >= Toolkit.getDefaultToolkit().getScreenSize().width) {
                            duck.resetPosition();
                        }
                        repaint();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        duck.stop();
                        break;
                    }
                }
            }
        }
                .start();
    }

    private void drawDucks(Graphics g) {
        for (Duck duck : duckGame.getDucks()) {
            duck.paintComponent(g);
        }
    }
}

And my Duck class:

public class Duck extends JComponent {
    private final static int INIT_X = -100;
    private int x = INIT_X;
    private int y = 100;
    private int width = 0;
    private int height = 0;
    private Image image = null;
    private boolean isDuckStopped = false;
    private final int STEP = 5;

    public Duck() {
        initRandomPosition();
        loadImage();
        setVisible(true);
        setBounds(x, y, width, height);
    }

    private void initRandomPosition() {
        y = getRandomY();
    }

    public void move() {
        x += STEP;
    }

    private void loadImage() {
        ImageIcon imageIcon = new ImageIcon(getFilePath(Images.DUCK.getFileName()));
        Dimension newDimension = Utils.getScaledDimension(100, 100, imageIcon.getIconWidth(), imageIcon.getIconHeight());
        image = imageIcon.getImage().getScaledInstance(newDimension.width, newDimension.height, Image.SCALE_DEFAULT);
        width = image.getWidth(null);
        height = image.getHeight(null);
    }


    @Override
    public void paintComponent(Graphics g) {
        super.paintComponents(g);
        drawDuck(g);
        Toolkit.getDefaultToolkit().sync();
    }

    private void drawDuck(Graphics g) {
        Graphics2D g2D = (Graphics2D) g;
        g2D.drawImage(image, x, y, this);
        setBounds(x, y, width, height);
    }

    public void stop() {
        isDuckStopped = true;
        setVisible(false);
    }

    public void resetPosition() {
        x = INIT_X;
        y = getRandomY();
    }
}
0

There are 0 best solutions below