2

The blue label is meant to move when you click and drag it. This works but the x / y position then jumps in a funny way.

Here's the code:

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

@SuppressWarnings("serial")
public class test extends JFrame implements MouseListener, MouseMotionListener {

private JPanel panel = new JPanel(null);    
private JLabel label1 = new JLabel();
private JLabel label2 = new JLabel();
private int mouseX = 200;
private int mouseY = 100;
private boolean drag = false;

public test() {
    this.add(panel);
    panel.setBackground(Color.WHITE);

    panel.add(label1);
    label1.setOpaque(true); 
    label1.setBackground(Color.BLUE);
    label1.setBounds(mouseX, mouseY, 100, 50);
    label1.addMouseMotionListener(this);
    label1.addMouseListener(this);

    panel.add(label2);
    label2.setOpaque(true); 
    label2.setBackground(Color.RED);
    label2.setBounds(mouseX + 200, mouseY, 100, 50);
    label2.addMouseMotionListener(this);
    label2.addMouseListener(this);
}

@Override
public void mousePressed(MouseEvent e) {
    if (e.getSource() == label1) {
        drag = true;
    } 
}

@Override
public void mouseReleased(MouseEvent e) {
    drag = false;
}

@Override
public void mouseDragged(MouseEvent e) {
    if (drag == true) {
        mouseX = e.getX();
        mouseY = e.getY();
        label1.setBounds(mouseX, mouseY, 100, 50);
    }
}

public void mouseMoved(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}

public static void main(String[] args) {
    test frame = new test();
    frame.setVisible(true);
    frame.setSize(600, 400);
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
javanna
  • 59,145
  • 14
  • 144
  • 125
jjj
  • 151
  • 2
  • 3
  • 6
  • possible duplicate of [dragging a jlabel around the screen](http://stackoverflow.com/questions/4893265/dragging-a-jlabel-around-the-screen) – Josh Lee Feb 04 '11 at 03:54

5 Answers5

4

Just put this on your MouseDragged method:

public void mouseDragged(MouseEvent e) 
{
    if (drag == true) 
    {
        JComponent jc = (JComponent)e.getSource();
        jc.setLocation(jc.getX()+e.getX(), jc.getY()+e.getY());
    }
}
Gianfranco
  • 41
  • 2
1

The coordinates returned by MouseEvent::getX() and MouseEvent::getY() represent the location of the event relative to the event's subject (i.e. relative to the label itself), which explains why your solution results in the label erratically jumping.

By using MouseEvent::getComponent() to grab the label and then querying its position (possibly relative to the position when dragging commenced), you can devise a working solution.

asdfjklqwer
  • 3,536
  • 21
  • 19
  • I understand what you mean when you speak off the relative position etc. but for some reason I cannot get the code to work. When I tried to create this: Component component = mouseEvent.getComponent(); and then call component.getX(); it didn't work – jjj Feb 04 '11 at 05:06
  • You can also solve this by getting screen positions of the JLabel, the JPanel that holds it and the mouse when you click on the label, then follow the mouse screen position as it's dragged and move the JLabel accordingly (relative to the JPanel/container). It's nothing more than basic vector addition. – Hovercraft Full Of Eels Feb 04 '11 at 22:03
1

Your problem is your setting your bounds based on the mouse location in the MouseListener, but the MouseListener has its location relative to the JLabel itself, but the JLabel's location should be set relative to the panel. You'll need to do some simple vector addition to figure this out.

edit: oops, I didn't see that this was already answered, and they say the same thing... sorry.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
1

Maybe try adding something like that The red one will do it better

private int clicX = 0;
private int clicY = 0;

public void mousePressed(MouseEvent e) {
drag = true;
if (e.getSource() == label1) {
}
if (e.getSource() == label2) {
    clicX = e.getX();
    clicY = e.getY();
}
}

public void mouseDragged(MouseEvent e) {

        if (e.getSource() == label2) {

        JComponent jc = (JComponent)e.getSource();
        jc.setLocation(jc.getX()+e.getX()-clicX, jc.getY()+e.getY()-clicY);
        }
Yi Jiang
  • 49,435
  • 16
  • 136
  • 136
MCR
  • 11
  • 1
0

Create two global variables:

int x_pressed = 0;
int y_pressed = 0;

then create two events (mousePressed and mouseDragged over JLabel):

lbl_banner.addMouseListener(new MouseAdapter()
{
    @Override
    public void mousePressed(MouseEvent e) {
        //catching the current values for x,y coordinates on screen
        x_pressed = e.getX();
        y_pressed = e.getY();
    }
});

lbl_banner.addMouseMotionListener(new MouseMotionAdapter(){
    @Override
    public void mouseDragged(MouseEvent e){
        //and when the Jlabel is dragged
        setLocation(e.getXOnScreen() - x_pressed, e.getYOnScreen() - y_pressed);
    }
});
compilex
  • 51
  • 4