0

I've added this listener to a JLabel, and I am able to drag the image around perfectly, However, as soon as I click on the panel(in an area where a JLabel is not present) the label returns back to it's original location. I can't figure out why that would happen. Please help me out, I've spent hours working on this. Thanks!

public class CardLabelListener extends MouseAdapter {

    private MouseEvent initiateEvent = null;

    @Override
    public void mouseReleased(MouseEvent me) {
        System.err.println("mouse release");
        int dx = me.getX() - initiateEvent.getX();
        int dy = me.getY() - initiateEvent.getY();
        if (Math.abs(dx) > 5 || Math.abs(dy) > 5) {
            Rectangle oldBound = me.getComponent().getBounds();
            int newX = oldBound.x + dx;
            int newY = oldBound.y + dy;
            me.getComponent().setBounds(newX, newY, oldBound.width, oldBound.height);
        }
        initiateEvent = null;
    }

    public void mousePressed(MouseEvent me) {
        GreetingCard.setBackground.findComponentAt(me.getX(), me.getY());
        System.err.println("mouse pressed");
        initiateEvent = me;
        me.consume();
    }

    public void mouseDragged(MouseEvent me) {
        System.err.println(me.getSource());
        if (initiateEvent == null) return;

        me.consume();
        JComponent jc = (JComponent) me.getSource();
        TransferHandler handler = jc.getTransferHandler();
        handler.exportAsDrag(jc, me, TransferHandler.MOVE);

        initiateEvent = null;
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
zoy.khan
  • 87
  • 1
  • 9

2 Answers2

2

Firstly, you're not dragging the icon, your dragging the component itself.

Secondly, you're fighting against the layout manager which contains the label component. When ever the panel is invalidated, the labels are returned to their original layout positions.

Trying using something like a JLayeredPane to put your labels in

UPDATED with example based on feedback

public class MoveMe {

    public static void main(String[] args) {
        new MoveMe();
    }

    public MoveMe() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new MoveMePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class MoveMePane extends JLayeredPane {

        public MoveMePane() {
            int width = 400;
            int height = 400;
            for (int index = 0; index < 10; index++) {
                String text = "Label " + index;
                JLabel label = new JLabel(text);
                label.setSize(label.getPreferredSize());

                int x = (int) Math.round(Math.random() * width);
                int y = (int) Math.round(Math.random() * height);
                if (x + label.getWidth() > width) {
                    x = width - label.getWidth();
                }
                if (y + label.getHeight() > width) {
                    y = width - label.getHeight();
                }
                label.setLocation(x, y);
                add(label);
            }

            MoveMeMouseHandler handler = new MoveMeMouseHandler();
            addMouseListener(handler);
            addMouseMotionListener(handler);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }
    }

    public class MoveMeMouseHandler extends MouseAdapter {

        private int xOffset;
        private int yOffset;
        private JLabel draggy;
        private String oldText;

        @Override
        public void mouseReleased(MouseEvent me) {
            if (draggy != null) {
                draggy.setText(oldText);
                draggy.setSize(draggy.getPreferredSize());
                draggy = null;
            }
        }

        public void mousePressed(MouseEvent me) {
            JComponent comp = (JComponent) me.getComponent();
            Component child = comp.findComponentAt(me.getPoint());
            if (child instanceof JLabel) {
                xOffset = me.getX() - child.getX();
                yOffset = me.getY() - child.getY();

                draggy = (JLabel) child;
                oldText = draggy.getText();
                draggy.setText("What a drag");
                draggy.setSize(draggy.getPreferredSize());
            }
        }

        public void mouseDragged(MouseEvent me) {
            if (draggy != null) {
                draggy.setLocation(me.getX() - xOffset, me.getY() - yOffset);
            }
        }
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • That panel's layout is set to Null, and it's a JTabbedPane. All my components(JLabel's that are going to move) are on that JTabbedPane, at the first tab. – zoy.khan Oct 30 '12 at 19:14
  • That info would have being handy to know before hand ;). On the mouseDragged event, I don't think it's necessary to export the via the transfer API. Simply set the components new location relative to the point it was clicked. I'm assuming the mouse listener is on the drag panel and not the individual labels – MadProgrammer Oct 30 '12 at 19:53
  • That helped, was wondering if you can give me a hand here: http://stackoverflow.com/questions/13149624/difficulty-in-resizing-an-image-which-is-stored-in-a-jlabel – zoy.khan Oct 31 '12 at 02:49
1

For this to work you would need use a null layout on the container where the JLabel is located, otherwise the position will reset to that where the current layout manager positions the label.

A better approach would be to use DragLayout

DragLayout was designed to replace a null layout. It will respect the location of a component. By default it will use the preferred size of the component to determines its size. Finally, it will automatically calculate the preferred size of the Container.

Reimeus
  • 158,255
  • 15
  • 216
  • 276
  • Or a JDesktopPane or a JLayerdPane – MadProgrammer Oct 30 '12 at 19:07
  • Hi,I already have the Layout set to null. rightPanel = new JTabbedPane(); rightPanel.setLayout(null); //and add my components at the first tab of the tabbed pane – zoy.khan Oct 30 '12 at 19:15
  • You guys are the best! I setLayout to Null every time I was using it, and my problem is resolved. Even though I had explicitly set it to null in one location, the other places didn't have it set to null. Thank you. – zoy.khan Oct 30 '12 at 19:20
  • http://stackoverflow.com/questions/13149624/difficulty-in-resizing-an-image-which-is-stored-in-a-jlabel – zoy.khan Oct 31 '12 at 02:51