简体   繁体   中英

Mouse Listener not working with a JFrame in Java

I'm trying to make a 2D game in Java. I need a way to detect mouse input for player attacks and some other stuff. I already have a working Key Listener in my game but when I tried adding a Mouse Listener the same way I did the Key Listener it doesn't work.

Here is my Mouse Listener class (Just some test codes for now and these line are never output in the console even when spamming my mouse everywhere on the display)

package input;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class MouseInput extends MouseAdapter
{
public MouseInput()
{

}

@Override
public void mouseClicked(MouseEvent e)
{
    System.out.println("Hello");
}

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

@Override
public void mouseReleased(MouseEvent e)
{
    System.out.println("Mouse Released");
}
}

Also here is my display class where I create a JFrame and I add my canvas, Key Listener and Mouse Listener to it.

package display;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JFrame;

import input.KeyInput;
import input.MouseInput;


public class Display
{
public static JFrame frame;
private Canvas canvas;

private String title;
private int width;
private int height;

private static double currtime = System.nanoTime();
private static double lasttime = 0;
private static double delta = 0;
private static float fps = 30;
private static int tick = 0;

public Display(String title, int width, int height)
{
    this.title = title;
    this.width = width;
    this.height = height;

    createDisplay();
}

private void createDisplay()
{
    frame = new JFrame(title);
    frame.setSize(width, height);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    frame.setFocusable(true);

    canvas = new Canvas();
    canvas.setPreferredSize(new Dimension(width, height));
    canvas.setMinimumSize(new Dimension(width, height));
    canvas.setMaximumSize(new Dimension(width, height));
    canvas.setBackground(Color.WHITE); 

    frame.add(canvas); 
    frame.addKeyListener(new KeyInput()); // Add the keyListener
    frame.addMouseListener(new MouseInput()); // Add the mouseListener
    frame.pack();
    System.out.println(frame.getMouseListeners().length + " mouse listener found"); // This line outputs 1 mouse listener found
    System.out.println(frame.getKeyListeners().length + " key listener found"); // This line outputs 1 key listener found

}

public void update() // Called every frame
{
    frame.requestFocus();
    tick++;
    lasttime = currtime;
    currtime = System.nanoTime();
    delta = (currtime - lasttime) / 1000000000;
    fps = (float) (1 / delta);
    if (tick / getFPS() >= 2)
    {
        tick = 0;
        System.out.println("FPS = " + Math.round(getFPS()));
        try
        {
            System.out.println("Mouse Position = " + frame.getMousePosition().getX()
                    + ", " + frame.getMousePosition().getY());
        }
        catch (Exception e)
        {
            System.out.println("Mouse out of screen. Could not get mouse position (NullPointerException)");
        }
    }
}

public int getWidth()
{
    return width;
}

public int getHeight()
{
    return height;
}

public Canvas getCanvas()
{
    return canvas;
}

public JFrame getFrame()
{
    return frame;
}

public static float getFPS()
{
    return fps;
}
}

I looked through this forum for answer but every answer given did not fix it.

Tell me if you need any more information to help you solve the problem and thanks in advance for helping :D

Add the MouseListener to the canvas object that covers the JFrame, and your code will work. Note that as a side recommendation, you shouldn't be mixing AWT with Swing components. Use a JPanel instead of a Canvas object.

Later we may touch on why KeyListeners should usually be avoided, but since that's not the thrust of your question, we can shelve this for now.

eg,

import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class Display2 extends JPanel {
    private int prefW;
    private int prefH;

    public Display2(int prefW, int prefH) {
        this.prefW = prefW;
        this.prefH = prefH;
        MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
        addMouseListener(myMouseAdapter);
        addMouseMotionListener(myMouseAdapter);
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(prefW, prefH);
    }

    private static void createAndShowGui() {
        Display2 mainPanel = new Display2(500, 500);

        JFrame frame = new JFrame("Display");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

class MyMouseAdapter extends MouseAdapter {
    @Override
    public void mousePressed(MouseEvent e) {
        System.out.printf("Mouse Pressed at: %s%n", e.getPoint());
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        System.out.printf("Mouse Released at: %s%n", e.getPoint());
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        System.out.printf("Mouse Dragged at: %s%n", e.getPoint());
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM