Dragging and moving a label on a window in Java

Hello everyone, so i'm doing a homework for my Java programming class related to a project i'm doing. I have four labels in in the form of a matrix each one will have a number or variable (1,2,3 and 4) and then i will have another 4 labels were i need to drag and put it on the corresponding label, like blue with the blue, yellow with the yellow,etc. If it's the correct one it will turn white but if it's the wrong one it will stay the same. I have this code but i'm having some problems doing the mouse drag event. So i would like to know if someone could give me some help or guide me on what i could do or how to use the mouse events for this case.

This is the code i have:

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

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

public class Pantalla extends JFrame {
private JFrame frame;
private JLabel l1,l2,l3,l4;
private JLabel j1,j2,j3,j4;
int x_pressed = 0;
int y_pressed = 0;
public Pantalla(){
frame = new JFrame("Practica.");
frame.setBounds(0,0,500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

l1 = new JLabel("1");
l1.setOpaque(true);
l1.setBackground(Color.blue);
l1.setForeground(Color.white);
frame.add(l1);

l2 = new JLabel("2");
l2.setOpaque(true);
l2.setBackground(Color.green);
frame.add(l2);

l3 = new JLabel("3");
l3.setOpaque(true);
l3.setBackground(Color.red);
frame.add(l3);

l4 = new JLabel("4");
l4.setOpaque(true);
l4.setBackground(Color.yellow);
frame.add(l4);

j1 = new JLabel(" ");
j1.setOpaque(true);
j1.setBackground(Color.BLUE);
frame.add(j1);

l1.setBounds(100,100,80,80);
l2.setBounds(200,100,80,80);
l3.setBounds(100,200,80,80);
l4.setBounds(200,200,80,80);
j1.setBounds(350,350,60,60);
j1.addMouseListener(new label1());
j1.addMouseMotionListener(new label1());

l1.setLayout(null);
l2.setLayout(null);
l3.setLayout(null);
l4.setLayout(null);
j1.setLayout(null);
frame.setLayout(null);
frame.setVisible(true);
}

class label1 implements MouseListener,MouseMotionListener{

	@Override
	public void mouseDragged(MouseEvent e) {
		// TODO Auto-generated method stub
		j1.setLocation();
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseClicked(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		x_pressed = e.getX();
        y_pressed = e.getY();
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		// TODO Auto-generated method stub
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub

	}

}

public static void main(String[] args){
	Pantalla fr = new Pantalla();
}

}

Any help is appreciate it :) Thanks in advance!

I would approach it like this:

  • have a field (lets say currentyMovingLabel) with which you track the currently moving label (make it a reference to the label object)
  • pressing the mouse on a label will set currentyMovingLabel
  • then you can use currentyMovingLabel to reference that label in the mouseMoved event, if it is null then you don't do anything, otherwise you update the location of the label to the location of the mouse
  • just before you remove the reference in mouseReleased, you can check if the coordinates of the label you're moving is in the range of another label (compare x and y coordinates with some margin, like 20px or something, trial and error)
  • if they overlap/are in the same area, set the text color to white
  • finally releasing the mouse will set the currentyMovingLabel to null, so no label will be moved afterwards, this is what you check against in the mouseMoved event

I hope this is clear enough, happy to elaborate if it isn't :)

Cheers

edit: forgot to include the checking if labels are correct

I'd like to suggest using GitHub Gist for code samples in the future, or using a code block.

1 Like

Hey guys thanks for the help i really appreciate it! :D

Right now i figured out how to move the labels :D Now i'm trying to make the another grid but i need to place the moving label over the correct label. I saw on same sites that this can be achieved using the OverlayLayout but i'm trying to use also GridBagLayout. Here's the code i have at the moment.

I can't help you there man :( I stopped using AWT a long time ago since it has now been replaced by JavaFX, and even then I'd have to search for a good way to do it. The steps I outlined in my earlier post would be the way to go if I were to do this on Android, where I'd use a FrameLayout, which just positions the views where you tell them to be, overlapping or not. If I were you, I would look into such a dumb view group, which just does whatever you ask of it and doesn't second guess you on the positioning of the views. If you have that, you could simply write some hit detection by checking X/Y coordinates. If you don't figure it out before the weekend I could maybe write up a code sample, probably in JavaFX then, which is way nicer imho :)

Cheers and good luck!

Thanks for your response, i really appreciate it! :)

Right now i got a timer on my project and i will implement the mouse events on the labels with the images. But i have a problem, i'm working with two different panels, one for the GridbagLayout and another GridbagLayout for the figures i need to move with the mouse. How i can move a label from one panel to another? I would try the hit detection for the X/Y coordinates.
Also when i move the mouse over the object it goes under the label, how i can make that the object i move goes over the label?

My first idea would be to try and remove the view from the 'moving'-layout/panel

movingGridBagLayout.remove(labelX);

then re-add the view to the 'static'-layout/panel

staticGridBagLayout.add(labelX);

Essentially what this does is re-assign the job of drawing and displaying the view on the screen to the static layout, it is still the same view. If you try to visualize that in your mind, it just moves it down a layer to a level where it can no longer be moved.

I think this might be a side effect of the OverlayLayout you're using. Have a look if it maybe has a setting where you can disable it overlaying the mouse. Good luck ;)

Cheers

Hello again, so i watched a video about collisions and one of my classmates told me about do the images with Rectangle instead of JLabels, i found this video:


It really helped me out doing what i wanted too :) The only problem is the mouse movement, i saw that the squere that has rectX and rectY (the blue one) is on coordinates (0,0), i tried to change that on this line :

g.drawImage(dbImage, 0, 0, this);

From the paint method but it makes the squere to be a little far from the cursor, even if i change the values of the mouseDragged doesn' t work, any idea of how i could change that to work that way?