Why can't I just use MouseAdapter, not MouseMotionAdapter? - java

My application's window can be moved around by dragging its menubar.
However, I don't understand why I have to use MouseMotionAdapter() to implement this feature.
Both classes have the method: mouseDragged(), so I erased MouseMotionAdapter and move the function into the MouseAdapter(). I could not drag the window anymore. Why?
This code works perfectly.
menuBar.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
}
});
//마우스로 매뉴를 잡고 움직일 수 있게 해주는 코드.
menuBar.addMouseMotionListener(new MouseMotionAdapter(){
#Override
public void mouseDragged(MouseEvent e) {
int x = e.getXOnScreen();
int y = e.getYOnScreen();
setLocation(x - mouseX, y - mouseY);
}
});
However, this doesn't
menuBar.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
}
#Override
public void mouseDragged(MouseEvent e) {
int x = e.getXOnScreen();
int y = e.getYOnScreen();
setLocation(x - mouseX, y - mouseY);
}
});
Thank you for your support

You can just use a MouseAdapter, but you have to call addMouseMotionListener so that mouse-motion events will get sent to it.
MouseAdapter ma = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
}
#Override
public void mouseDragged(MouseEvent e) {
int x = e.getXOnScreen();
int y = e.getYOnScreen();
setLocation(x - mouseX, y - mouseY);
}
});
menuBar.addMouseListener(ma);
menuBar.addMouseMotionListener(ma);
Only a listener registered with addMouseMotionListener will be sent mouse-motion events, like dragging.
From the MouseAdapter docs:
Create a listener object using the extended class and then register it with a component using the component's addMouseListener, addMouseMotionListener, addMouseWheelListener methods.

Related

Detecting a mouse hover over an object that is not a JComponent

As the title states, I am trying to detect a mouse hover over an object that is not a JComponent.
Right now I have a window with a green JPanel. When you left-click on this JPanel you create a point.
What I am trying to do is to have extra information displayed when I hover over these points. However, I have no idea how to even begin detecting if I am hovering my mouse over a point. I tried looking into the MouseListener interface but I could not find any examples of people using MouseListener with an object. I have only seen people use MouseListener with JComponents. I would preferably like to have this mouse hover detection code in my Point class if possible to keep my code clean.
JPanel Code
class Map extends JPanel implements MouseListener {
public static ArrayList<Point> points = new ArrayList<Point>(); //array for the points
public Map() {
this.setBackground(Color.green);
this.setPreferredSize(new Dimension(1280, 720));
this.addMouseListener(this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D graphics = (Graphics2D) g;
drawPoints(graphics);
}
private void drawPoints(Graphics2D graphics) {
for(int i = 0; i < points.size(); i++) {
points.get(i).drawPoint(graphics);
}
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
if(e.getButton() == MouseEvent.BUTTON1) { //Left Click
points.add(new Point(e.getX(), e.getY()));
repaint();
}
else if(e.getButton() == MouseEvent.BUTTON3) { //right click
for(int i = points.size() - 1; i >= 0; i--) { //loop backwards so if points overlap remove the one on top first
Point current = points.get(i);
if( Math.abs( e.getX() - current.x ) < current.size/2 && Math.abs( e.getY() - current.y ) < current.size/2 ) {
points.remove(i);
repaint();
break;
}
}
}
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
Point Code
public class Point {
public int x, y;
public int size = 10;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public Point() {
this.x = 0;
this.y = 0;
}
public void drawPoint(Graphics2D graphics) {
graphics.setPaint(Color.black);
graphics.setStroke(new BasicStroke(5));
graphics.drawOval(x - (size/2), y - (size/2), size, size);
graphics.setPaint(Color.red);
graphics.fillOval(x - (size/2), y - (size/2), size, size);
}
public void drawInfo(Graphics2D graphics) {
graphics.drawString("test", x, y);
}
}
I had the same issue with a Packet-Tracer-Like program, where I drew rects.
If they are just points, I would check if the mouse cords are the same as the point cords when the mouse is moved.
#Override
public void mouseMoved(MouseEvent e) {
entered = false;
if(point.x == e.getX() && point.y == e.getY()){
entered = true;
}
}
If although, like in my case, the drawn object has a width and a height, it gets messier.
#Override
public void mouseMoved(MouseEvent e) {
entered = false;
if((e.getX() <= point.x+width) && (e.getX() >= point.x)){
if((e.getY() <= point.y+height) && (e.getY() >= point.y)){
entered = true;
}
}
}

Java - boolean set to false with nothing telling it to do so

My boolean drawFlag is being set to false in my code with nothing visible actually telling it to change value to false. This is preventing the code inside method mouseDragged(mouseEvent) to execute. If someone could point out what's making the flag become false so this would stop happening? Thanks.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class DrawAndDrag {
public static void main(String[] args) throws InterruptedException {
GraphicsFrame window = new GraphicsFrame("Draw Rectangle");
window.init();
}
}
class GraphicsFrame extends JFrame {
public GraphicsFrame(String title) {
super(title);
}
public void init() {
Container pane = this.getContentPane();
pane.add(new GraphicsContent().init());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600, 600);
this.setVisible(true);
}
}
class GraphicsContent extends JPanel {
private int xStart, yStart;
private int width, height;
public JPanel init() {
this.setBackground(Color.WHITE);
this.addMouseListener(new MouseDrag());
this.addMouseMotionListener(new MouseDrag());
return this;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(xStart, yStart, width, height);
}
class MouseDrag implements MouseListener, MouseMotionListener {
private boolean drawFlag;
public void mousePressed(MouseEvent e) {
if(isOutside(e)) {
this.drawFlag = true;
xStart = e.getX();
yStart = e.getY();
width = 0; height = 0;
System.out.println(drawFlag);
}else {
// this.drawFlag = false;
}
}
public void mouseDragged(MouseEvent e) {
System.out.println(drawFlag);
if(drawFlag) {
width = e.getX() - xStart;
height = e.getY() - yStart;
repaint();
}
}
public boolean isOutside(MouseEvent e) {
int xMin = Math.min(xStart, xStart + width); int yMin = Math.min(yStart, yStart + height);
int xMax = Math.max(xStart, xStart + width); int yMax = Math.max(yStart, yStart + height);
if((e.getX() < xMin || e.getX() > xMax)
|| (e.getY() < yMin || e.getY() > yMax)) {
return true;
}else {
return false;
}
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
}
}
Try to move drawFlag attribute from the inner class MouseDrag to the outer class GraphicsContent as follow
class GraphicsContent extends JPanel {
private int xStart, yStart;
private int width, height;
private volatile boolean drawFlag;
// other code
}
However as you drag, the value is constantly being reported as being false
You've got two listeners. One is a motion listener:
this.addMouseListener(new MouseDrag());
this.addMouseMotionListener(new MouseDrag());
mousePressed will not be called on a motion listener, so it will always be false in the drag event.
I expect what you meant is this:
MouseDrag listener = new MouseDrag();
this.addMouseListener(listener);
this.addMouseMotionListener(listener);
Are you sure you need two MouseDrag elements? I.e. using something like
public JPanel init() {
this.setBackground(Color.WHITE);
MouseDrag md = new MouseDrag();
this.addMouseListener(md);
this.addMouseMotionListener(md);
return this;
}
I can at least plot a blue square....

In Java, my MouseMotionListener and MouseListener is detecting clicks, but not movement

so I am creating a java game and and here is my mouse's clicks are being detected but the mouseMoved is not being run at all. There is a print statement in the method which never gets run. I am really stuck because since the clicks are being registered across the window, there shouldn't be anything wrong with the mouse motion.
Is the mouse dependent on anything else because I really have no idea what is causing this.
Thanks.
public class Mouse implements MouseListener, MouseMotionListener{
private static int mouseX = -1;
private static int mouseY = -1;
private static int mouseB = -1;
public static int getX(){
return mouseX;
}
public static int getY(){
return mouseY;
}
public static int getB(){
return mouseB;
}
public void mouseMoved(MouseEvent e) {
System.out.println("Mouse Moved");
mouseX = e.getX();
mouseY = e.getY();
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {
mouseB = e.getButton();
System.out.println(e.getX() + " " + e.getY());
}
public void mouseReleased(MouseEvent e) {
mouseB = -1;
}
public void mouseDragged(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {
}
}
Here is my game constructor which initiates everything.
public Game(){
//cCursor();
screen = new Screen(WIDTH, HEIGHT);
mouse = new Mouse();
keys = new Keyboard();
//level = new RandomLevel(64, 64);
level = Level.spawn;
TileCoord pSpawn = new TileCoord(20,66);
player = new Player(pSpawn.x(), pSpawn.y(), keys);
player.init(level);
addKeyListener(keys);
addMouseListener(mouse);
}
MouseMoitionListener is a different listener to MouseListener and needs to be registered separately...
Start by adding a call to addMouseMotionListener
addMouseListener(mouse);
addMouseMotionListener(mouse);
Have a look at How to Write a Mouse Listener for more details

How to add mouselistener on random drawn image in java?

I am building a game in Java and I need to add a mouselistener to an random drawn image in my game.
I made the image appear on random places every x seconds, when I click the image I would like to add 1 point to the scoreboard.
My code for the random image adding is:
Random rand = new Random();
private int x = 0;
private int y = 0;
Timer timer = new Timer(700, new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
x = rand.nextInt(400);
y = rand.nextInt(330);
repaint();
}
});
public void mousePressed (MouseEvent me) {
// Do something here
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(achtergrond, 0, 0, this.getWidth(), this.getHeight(), null);
//g.drawImage(muisje, 10, 10, null);
g.drawImage(muisje, x, y, 100, 100, this);
}
I looked on google and found that I need to add a new class with a mouse event, but How do I add this? It's not clear enough because I'm just a beginner in Java.
You know where the image is drawn (x,y) and you know the size of the image (100,100), therefore to tell if the mouse click is inside the image you can do something like this:
public void mousePressed (MouseEvent me) {
int clickX = me.getXOnScreen();
int clickY = me.getYOnScreen();
if(clickX > x && clickX < x+100 && clickY > y && clickY < y+100) {
//the image has been clicked
}
repaint();
}
The class you're writing can then implement MouseListener.
EDIT in response to comment:
You don't need to link the code to the image, the component that you're writing should implement the mouse listener since this maintains the state and knows where the image is drawn. I would start out by looking at this link and implementing a basic MouseListener to print out the x and y co-ordinates of mouse clicks on your component:
http://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html
Example component implementing Mouse Listener:
public class TestComponent extends JComponent implements MouseListener {
public TestComponent() {
this.addMouseListener(this);
}
#Override
public void mouseClicked(MouseEvent e) {
int clickedX = e.getX();
int clickedY = e.getY();
System.out.println("User Clicked: " + clickedX + ", " + clickedY);
}
#Override
public void mousePressed(MouseEvent e) {}
#Override
public void mouseReleased(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
}
You need to register a MouseListener for your Gamevenster class. Instead of making the class implement MouseListener, just use a MouseAdapter, where you only have to implement the method mouseClicked. So in your constructor, you something like this
private JLabel scoreLabel = new JLabel("Score: " + score);
private int score = 0;
public Gamevenster() {
scoreLabel.setFont(new Font("impact", Font.PLAIN, 30));
scoreLabel.setForeground(Color.WHITE);
add(scoreLabel);
addMouseListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent e) {
Point p = e.getPoint();
int clickX = (int)p.getX();
int clickY = (int)p.getY();
if(clickX > x && clickX < x + 100 && clickY > y && clickY < y + 100) {
score++;
scoreLabel.setText("Score: " + score);
}
}
});
}

Visual marker of mouse clicks using Java

I am creating a screen recorder software using Java. Almost 80% work has been completed. Now I need to create a visual marker of mouse clicks using Java. So that I can see in the playback video that where the mouse has been clicked. How can I do that?
Does anyone have any code example?
Very simple. Read the point where the mouse is clicked by the user with getX() and getY() methods of MouseListener. At the point, draw a oval with drawOval() methods of java.awt.Graphics class. Try the following code which I am sure solves your problem.
import java.awt.*;
import java.awt.event.*;
// no window closing code
public class MouseXY extends Frame implements MouseListener, MouseMotionListener
{
int x , y;
String str =" ";
public MouseXY()
{
setSize(500, 500);
setVisible(true);
addMouseListener(this); // register both the listeners with frame
addMouseMotionListener(this);
} // override the 5 abstract methods of ML
public void mouseEntered(MouseEvent e)
{
setBackground(Color.green);
x = e.getX();
y = e.getY();
str ="Mouse Entered";
repaint();
}
public void mouseExited(MouseEvent e)
{
setBackground(Color.red);
x = e.getX();
y = e.getY();
str ="Mouse Exited";
repaint();
}
public void mouseClicked(MouseEvent e)
{
setBackground(Color.gray);
x = e.getX();
y = e.getY();
str ="Mouse Clicked";
repaint();
}
public void mouseReleased(MouseEvent e)
{
setBackground(Color.blue);
x = e.getX();
y = e.getY();
str ="Mouse Released";
repaint();
}
public void mousePressed(MouseEvent e)
{
setBackground(Color.lightGray);
x = e.getX();
y = e.getY();
str ="Mouse pressed";
repaint();
} // override the 2 abstract methods of MML
public void mouseDragged(MouseEvent e)
{
setBackground(Color.magenta);
x = e.getX();
y = e.getY();
str ="Mouse Dragged";
repaint();
}
public void mouseMoved(MouseEvent e)
{
setBackground(Color.yellow);
x = e.getX();
y = e.getY();
str = "Mouse Moved";
repaint();
}
public void paint(Graphics g)
{
g.setColor(Color.blue);
g.fillOval(x , y , 10 , 10);
g.drawString(x +", "+ y , x , y);
g.drawString(str , x , y -10); // to draw the string above y coordinate
}
public static void main(String args[ ])
{
new MouseXY();
}
}

Categories