Moving a JLabel Around JPanel

10,232

Solution 1

Here is what I wanted:

public class LayerItem extends JLabel{

    protected int lblYPt = 0;

    public LayerItem(JPanel layers){
        this.addMouseListener(new MouseAdapter(){
            @Override
             public void mousePressed(MouseEvent evt){
                 lblMousePressed(evt);
             }
        });

        this.addMouseMotionListener(new MouseAdapter(){
            @Override
            public void mouseDragged(MouseEvent evt){
                lblMouseDragged(evt);
            }
        });
    }

    public void lblMousePressed(MouseEvent evt){
        lblYPt = evt.getY();
    }

    public void lblMouseDragged(MouseEvent evt){
        Component parent = evt.getComponent().getParent();
        Point mouse = parent.getMousePosition();
        try{
            if(mouse.y - lblYPt >= 30){
                this.setBounds(0, mouse.y - lblYPt, 198, 50);
            }
        }catch(Exception e){
        }
    }
}

Solution 2

Start playing with this:

public class ComponentDragger extends MouseAdapter {

     private Component target;

    /**
     * {@inheritDoc}
     */
    @Override
    public void mousePressed(MouseEvent e) {
        Container container = (Container) e.getComponent();
        for (Component c : container.getComponents()) {
            if (c.getBounds().contains(e.getPoint())) {
                target = c;
                break;
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void mouseDragged(MouseEvent e) {
        if (target != null) {
            target.setBounds(e.getX(), e.getY(), target.getWidth(), target.getHeight());
            e.getComponent().repaint();
            }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void mouseReleased(MouseEvent e) {
        target = null;
    }

    public static void main(String[] args) {
        JLabel label = new JLabel("Drag Me");
        JPanel panel = new JPanel();
        panel.add(label);
        ComponentDragger dragger = new ComponentDragger();
        panel.addMouseListener(dragger);
        panel.addMouseMotionListener(dragger);
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(1024, 768);
        f.add(panel);
        f.setVisible(true);
        panel.setLayout(null);
        f.setState(Frame.MAXIMIZED_BOTH);
    }
}

Solution 3

Here's another example of this where the MouseListener and MouseMotionListener are on the JLabels themselves. For this to work, it needs to know the mouse's location on the screen vs it's initial location on screen when the mouse was initially pressed.

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class MovingLabels {
   private static final int PREF_W = 800;
   private static final int PREF_H = 600;

   private static void createAndShowGui() {
      Random random = new Random();
      final JPanel panel = new JPanel();

      Color[] colors = {Color.red, Color.orange, Color.yellow, Color.green, Color.blue, Color.cyan};
      panel.setPreferredSize(new Dimension(PREF_W, PREF_H)); // sorry kleopatra
      panel.setLayout(null);

      MyMouseAdapter myMouseAdapter = new MyMouseAdapter();

      for (int i = 0; i < colors.length; i++) {
         Color c = colors[i];
         JLabel label = new JLabel("Label " + (i + 1));
         Border outsideBorder = new LineBorder(Color.black);
         int eb = 10;
         Border insideBorder = new EmptyBorder(eb, eb, eb, eb);
         label.setBorder(BorderFactory.createCompoundBorder(outsideBorder , insideBorder));
         label.setSize(label.getPreferredSize());
         label.setBackground(c);
         label.setOpaque(true);
         int x = random.nextInt(PREF_W - 200) + 100;
         int y = random.nextInt(PREF_H - 200) + 100;
         label.setLocation(x, y);
         label.addMouseListener(myMouseAdapter);
         label.addMouseMotionListener(myMouseAdapter);
         panel.add(label);
      }

      JFrame frame = new JFrame("MovingLabels");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(panel);
      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 {

   private Point initialLoc;
   private Point initialLocOnScreen;

   @Override
   public void mousePressed(MouseEvent e) {
      Component comp = (Component)e.getSource();
      initialLoc = comp.getLocation();
      initialLocOnScreen = e.getLocationOnScreen();
   }

   @Override
   public void mouseReleased(MouseEvent e) {
      Component comp = (Component)e.getSource();
      Point locOnScreen = e.getLocationOnScreen();

      int x = locOnScreen.x - initialLocOnScreen.x + initialLoc.x;
      int y = locOnScreen.y - initialLocOnScreen.y + initialLoc.y;
      comp.setLocation(x, y);
   }

   @Override
   public void mouseDragged(MouseEvent e) {
      Component comp = (Component)e.getSource();
      Point locOnScreen = e.getLocationOnScreen();

      int x = locOnScreen.x - initialLocOnScreen.x + initialLoc.x;
      int y = locOnScreen.y - initialLocOnScreen.y + initialLoc.y;
      comp.setLocation(x, y);
   }
}

Solution 4

You are probably getting it for the label itself. Try observing the coordinates of the panel. It should work

Share:
10,232
Get Off My Lawn
Author by

Get Off My Lawn

Currently working on a node web framework Red5 Http Server, which is still just beta, but feel free to check it out! Any feedback would be great! You can checkout the code on Github, this includes the website, installer and framework. Thanks for checking it out!

Updated on June 04, 2022

Comments

  • Get Off My Lawn
    Get Off My Lawn almost 2 years

    I have a JPanel that has 2+ JLables on it, I would like to be able to grab a label then move it to a different location on the JPanel. How can I do that? The only things I can find on this are moving a label from component "A" to component "B", nothing about moving it around on a Panel.