1

I'm just learning java and I have a project where I want to be able to move a JLabel around a window with my mouse.

I set up a class called BasicWindow1, implemented a MouseMotionListener, instantiated a JFrame container, added a JLabel to the JFrame, set up a mouseDragged method, hooked up the setBounds method of the JLabel to the MouseEvent information, compiled it and it ran ...

BUT ......

when I dragged the JLabel a second GHOST label appeared above it and moved happily along with its virtual brother.

I've included the code below and I'm hoping someone will take an interest and straighten me out. I'm guessing it's probably a simple beginner's mistake, but it's driving me crazy.

On the debugging level, I inserted a println(e) with the MouseEvent in the mouseDragged method and it showed that the MOUSE_DRAGGED x,y elements were oscillating between 2 distinct x,y paths, one for the GHOST and one for its virtual brother.

Thanks for looking, Mike

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class BasicWindow1 implements MouseMotionListener {

   JFrame jf = new JFrame();
   JLabel label2 = new JLabel("label2");
      
   public BasicWindow1(String string) {

      //JFrame
      jf.setTitle(string);
      jf.setSize(400,400);   
      jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      jf.setLayout(null);
      jf.setVisible(true);

      label2.setOpaque(true);
      label2.setBackground(Color.cyan);
      label2.setBounds(0,150,75,25);
      label2.addMouseMotionListener(this);
      jf.add(label2);
          
   }//end constructor
      
   public void mouseDragged(MouseEvent e) {
      label2.setBounds(e.getX(),e.getY(),75,25);
      System.out.println("e =  " + e); 
  }
   public void mouseMoved(MouseEvent e) {}

   public static void main(String[] args) {
      BasicWindow1 mybw = new BasicWindow1("Basic Window for Stack Overflow");
   }
}
Mike
  • 13
  • 3
  • It must be because of the difference between [getY()](https://docs.oracle.com/javase/8/docs/api/java/awt/event/MouseEvent.html#getY--) and [getYOnScreen()](https://docs.oracle.com/javase/8/docs/api/java/awt/event/MouseEvent.html#getYOnScreen--). With the latter there is no oscillation (although the offset is a bit off). There's probably a logic behind it related to the "position of the event relative to the source component", but I just woke up. Here's how to create a [draggable component](https://stackoverflow.com/questions/874360/swing-creating-a-draggable-component). – Kayaman Nov 13 '20 at 06:40

1 Answers1

1

Your problem is that you added the MouseMotionListener to the wrong component. You need to add it to the parent of label2, which is the content pane of jf.

Try the following code.

import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class BasicWindow1 implements MouseMotionListener {

    JFrame jf = new JFrame();
    JLabel label2 = new JLabel("label2");

    public BasicWindow1(String string) {

        // JFrame
        jf.setTitle(string);
        jf.setSize(400, 400);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setLayout(null);
        jf.setVisible(true);

        label2.setOpaque(true);
        label2.setBackground(Color.cyan);
        label2.setBounds(0, 150, 75, 25);
        jf.getContentPane().addMouseMotionListener(this); // CHANGE HERE
        jf.add(label2);

    }// end constructor

    public void mouseDragged(MouseEvent e) {
        label2.setLocation(e.getX(), e.getY()); // CHANGE HERE
    }

    public void mouseMoved(MouseEvent e) {
    }

    public static void main(String[] args) {
        BasicWindow1 mybw = new BasicWindow1("Basic Window for Stack Overflow");
    }
}

Method getX() and getY(), in class MouseEvent, return the location of the mouse pointer in the coordinate space of the component that you added the MOuseMotionListener to. In your case this is the location of the mouse pointer inside the JLabel but that's not what you want. You want the location of the mouse pointer in the coordinate space of the component that you want to drag the JLabel around in which is the JFrame or more precisely the content pane of the JFrame.

For an alternative solution, refer to dragging a jlabel around the screen

Abra
  • 19,142
  • 7
  • 29
  • 41