单击鼠标在JLabel内拖动并移动图片

时间:2012-10-29 21:57:35

标签: java image swing drag jlabel

我在JLabel中有一个图像。

JLabel label = new JLabel(new ImageIcon("C:\\image.jpg"));
label.setSize(300,300);

我想要以下功能。

- 我点击JLabel内的一个位置(在图像上)。

- 按下鼠标按钮,我可以在JLabel中更改图像的位置。 (我将图片拖到JLabel内的不同位置)

嗯,这意味着在很多情况下,图片将被裁剪并在视图之外。

请告诉我如何实现此功能?

要添加到JLabel的正确事件侦听器是什么?

3 个答案:

答案 0 :(得分:4)

首先,我建议使用布局而不是setLayout(null)和setBounds()。其次,从JLabel中分离ImageIcon。最后,将JLabel和ImageIcon设置为字段而不是局部变量。

您需要添加MouseListener和MouseMotionListener。

label.addMouseMotionListener(new MouseAdapter()
{
    public void mouseMoved(MouseEvent arg0)
    {
        if(clicked)
        {
            label.x++
            label.y++
            label.repaint();
        }
    }
});

label.addMouseListener(new MouseAdapter()
{
    public void mousePressed(MouseEvent arg0)
    {
        clicked = !clicked;
    }
});

(对不起事先提出罗嗦)

这会使标签的图像出现在标签所在的位置,当您将鼠标悬停在标签上时,它将向东南方向移动。我创建了一个新的标签类,我在其中覆盖paintComponent并在其中添加了一个绘图图标图标方法,其中x和y是变量。想法是计算标签上的中心点,然后向西移动该点(x--)向西移动图像的x位置,向南移动(y--),等等。这只会在标签内移动您的图像。如果您的鼠标位于标签之外,则移动会停止。如果图像的某些部分位于标签之外,则不会显示该部分。我会覆盖你的标签类中的paint compoent并移动图像,然后为每个动作设置图标。

public class Label1 extends JLabel
{
    public int x;
    public int y;
    ImageIcon imageIcon = new ImageIcon("path");

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
//No setLocation(x, y) method exists for an image icon or an image. You are on your own on this
        imageIcon.setLocation(x, y);
        label.setIcon(imageIcon);
    }
}

答案 1 :(得分:4)

这是一个基本的例子......

它的工作原理是将标签分成3x3网格,其中每个单元格代表图标的可能位置。

public class TestMouseDrag {

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

    public TestMouseDrag() {
        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 DragMyIcon());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    protected class DragMyIcon extends JPanel {

        private JLabel label;

        public DragMyIcon() {

            ImageIcon icon = null;

            try {
                icon = new ImageIcon(ImageIO.read(getClass().getResource("/bomb.png")));
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            label = new JLabel(icon);
            label.setHorizontalAlignment(JLabel.CENTER);
            label.setVerticalAlignment(JLabel.CENTER);

            setLayout(new BorderLayout());
            add(label);

            MouseHandler handler = new MouseHandler();
            label.addMouseListener(handler);
            label.addMouseMotionListener(handler);

        }

    }

    protected class MouseHandler extends MouseAdapter {

        private boolean active = false;

        @Override
        public void mousePressed(MouseEvent e) {

            JLabel label = (JLabel) e.getComponent();
            Point point = e.getPoint();

            active = getIconCell(label).contains(point);
            if (active) {
                label.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
            } else {
                label.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            }

        }

        @Override
        public void mouseReleased(MouseEvent e) {
            active = false;
            JLabel label = (JLabel) e.getComponent();
            label.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            if (active) {
                JLabel label = (JLabel) e.getComponent();
                Point point = e.getPoint();

                int verticalAlign = label.getVerticalAlignment();
                int horizontalAlign = label.getHorizontalAlignment();

                if (isWithInColumn(label, point, 0)) {
                    horizontalAlign = JLabel.LEFT;
                } else if (isWithInColumn(label, point, 1)) {
                    horizontalAlign = JLabel.CENTER;
                } else if (isWithInColumn(label, point, 2)) {
                    horizontalAlign = JLabel.RIGHT;
                }

                if (isWithInRow(label, point, 0)) {
                    verticalAlign = JLabel.TOP;
                } else if (isWithInRow(label, point, 1)) {
                    verticalAlign = JLabel.CENTER;
                } else if (isWithInRow(label, point, 2)) {
                    verticalAlign = JLabel.BOTTOM;
                }

                label.setVerticalAlignment(verticalAlign);
                label.setHorizontalAlignment(horizontalAlign);

                label.invalidate();
                label.repaint();

            }
        }

        @Override
        public void mouseMoved(MouseEvent e) {
        }

        protected boolean isWithInColumn(JLabel label, Point p, int gridx) {
            int cellWidth = label.getWidth() / 3;
            int cellHeight = label.getHeight();

            Rectangle bounds = new Rectangle(gridx * cellWidth, 0, cellWidth, cellHeight);

            return bounds.contains(p);
        }

        protected boolean isWithInRow(JLabel label, Point p, int gridY) {
            int cellWidth = label.getWidth();
            int cellHeight = label.getHeight() / 3;

            Rectangle bounds = new Rectangle(0, cellHeight * gridY, cellWidth, cellHeight);

            return bounds.contains(p);
        }

        private Rectangle getIconCell(JLabel label) {

            Rectangle bounds = new Rectangle();

            int cellWidth = label.getWidth() / 3;
            int cellHeight = label.getHeight() / 3;

            bounds.width = cellWidth;
            bounds.height = cellHeight;

            if (label.getHorizontalAlignment() == JLabel.LEFT) {
                bounds.x = 0;
            } else if (label.getHorizontalAlignment() == JLabel.CENTER) {
                bounds.x = cellWidth;
            } else if (label.getHorizontalAlignment() == JLabel.RIGHT) {
                bounds.x = cellWidth * 2;
            } else {
                bounds.x = 0;
                bounds.width = 0;
            }
            //if (label.getHorizontalAlignment() == JLabel.TOP) {
            //    bounds.y = 0;
            //} else if (label.getHorizontalAlignment() == JLabel.CENTER) {
            //    bounds.y = cellHeight;
            //} else if (label.getHorizontalAlignment() == JLabel.BOTTOM) {
            //    bounds.y = cellHeight * 2;
            //} else {
            //    bounds.y = 0;
            //    bounds.height = 0;
            //}
            if (label.getVerticalAlignment() == JLabel.TOP) {
                bounds.y = 0;
            } else if (label.getVerticalAlignment() == JLabel.CENTER) {
                bounds.y = cellHeight;
            } else if (label.getVerticalAlignment() == JLabel.BOTTOM) {
                bounds.y = cellHeight * 2;
            } else {
                bounds.y = 0;
                bounds.height = 0;
            }

            return bounds;

        }

    }

}

根据反馈更新

此示例基本上使用JLayerdPane来允许在其容器中重新定位JLabels ...

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);
            }
        }
    }
}

答案 2 :(得分:1)

此修改示例基于MadProgrammer的代码。

它显示了我在原帖中描述的行为。谢谢大家的宝贵帮助,特别是MadProgrammer和Coupon22。尝试一下。

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

public class TestMouseDrag {

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

public TestMouseDrag() {
    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 DragMyIcon("C://image.jpg"));
            frame.pack();
            frame.setSize(500,500);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    });
}

protected class DragMyIcon extends JPanel {

    public static final long serialVersionUID = 172L;
    private JLabel label;

    public DragMyIcon(String path) {
        setLayout(null);

        ImageIcon icon = null;

        icon = new ImageIcon(path);

        label = new JLabel(icon);
        label.setBounds(0,0,icon.getIconWidth(), icon.getIconHeight());
        setBounds(0,0,icon.getIconWidth(), icon.getIconHeight());
        label.setHorizontalAlignment(JLabel.CENTER);
        label.setVerticalAlignment(JLabel.CENTER);

        add(label);

        MouseHandler handler = new MouseHandler();
        label.addMouseListener(handler);
        label.addMouseMotionListener(handler);

    }

}

protected class MouseHandler extends MouseAdapter {

    private boolean active = false;
    private int xDisp;
    private int yDisp;

    @Override
    public void mousePressed(MouseEvent e) {
        active = true;
        JLabel label = (JLabel) e.getComponent();

        xDisp = e.getPoint().x - label.getLocation().x;
        yDisp = e.getPoint().y - label.getLocation().y;

        label.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        active = false;
        JLabel label = (JLabel) e.getComponent();
        label.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        if (active) {
            JLabel label = (JLabel) e.getComponent();
            Point point = e.getPoint();
            label.setLocation(point.x - xDisp, point.y - yDisp);
            label.invalidate();
            label.repaint();

        }
    }

    @Override
    public void mouseMoved(MouseEvent e) {
    }
}

}