Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用鼠标单击在JLabel中拖动和移动图片_Java_Image_Swing_Drag_Jlabel - Fatal编程技术网

Java 使用鼠标单击在JLabel中拖动和移动图片

Java 使用鼠标单击在JLabel中拖动和移动图片,java,image,swing,drag,jlabel,Java,Image,Swing,Drag,Jlabel,我在一个JLabel中有一个图像 JLabel label = new JLabel(new ImageIcon("C:\\image.jpg")); label.setSize(300,300); 我想要以下功能 -我单击JLabel内部的一个位置(在图像上) -按下鼠标按钮,我可以更改图像在JLabel中的位置。(我将图片拖动到JLabel中的不同位置) 嗯,这意味着在很多情况下,图片会被裁剪,并且在视野之外 请告诉我如何实现此功能 要添加到我的JLabel中的正确事件侦听器是什么?首先,

我在一个JLabel中有一个图像

JLabel label = new JLabel(new ImageIcon("C:\\image.jpg"));
label.setSize(300,300);
我想要以下功能

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

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

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

请告诉我如何实现此功能


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

首先,我建议使用布局而不是setLayout(null)和setBounds()。其次,将ImageIcon与JLabel分离。最后,将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;
    }
});
(对不起,事先说得太多了)

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

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

这是一个基本的例子

它的工作原理是将标签分成一个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);
            }
        }
    }
}
公共类MoveMe{
公共静态void main(字符串[]args){
新MoveMe();
}
公共运动{
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}捕获(ClassNotFoundException ex){
}catch(实例化异常){
}捕获(非法访问例外){
}捕获(无支持的LookandFeelexception ex){
}
JFrame=新JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(新的BorderLayout());
frame.add(newmovemepane());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类MoveMePane扩展了JLayeredPane{
公共移动窗格(){
整数宽度=400;
内部高度=400;
对于(int-index=0;index<10;index++){
String text=“Label”+索引;
JLabel标签=新的JLabel(文本);
label.setSize(label.getPreferredSize());
int x=(int)Math.round(Math.random()*宽度);
int y=(int)Math.round(Math.random()*高度);
如果(x+label.getWidth()>width){
x=width-label.getWidth();
}
如果(y+label.getHeight()>width){
y=宽度-label.getHeight();
}
标签设置位置(x,y);
添加(标签);
}
MoveMeMouseHandler=新的MoveMeMouseHandler();
addMouseListener(handler);
addMouseMotionListener(处理程序);
}
@凌驾
公共维度getPreferredSize(){
返回新维度(400400);
}
}
公共类MoveMeMouseHandler扩展了MouseApter{
私有int-xOffset;
私人内部补偿;
二等兵杰拉贝尔·德拉吉;
私有字符串oldText;
@凌驾
公共无效MouseEvent me(MouseEvent me){
if(draggy!=null){
draggy.setText(旧文本);
draggy.setSize(draggy.getPreferredSize());
draggy=null;
}
}
public void mousePressed(MouseEvent me){
JComponent comp=(JComponent)me.getComponent();
Component child=comp.findComponentAt(me.getPoint());
if(JLabel的子实例){
xOffset=me.getX()-child.getX();
yOffset=me.getY()-child.getY();
draggy=(JLabel)儿童;
oldText=draggy.getText();
draggy.setText(“真讨厌”);
draggy.setSize(draggy.getPreferredSize());
}
}
公共无效鼠标标记(MouseEvent me){
if(draggy!=null){
setLocation(me.getX()-xOffset,me.getY()-yOffset);
}
}
}
}

此修改后的示例基于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) {
    }
}

}

您很可能需要创建一个扩展JLabel的类。为什么它需要是一个
JLabel
?Robin,您建议我使用什么来实现此功能?在思考图像时,首先想到的是JLabel,但我是图像方面的高手,真的。你需要添加一个鼠标听筒。正如代码大师所说,您还需要创建一个扩展JLabel并覆盖paintComponent的类。在paintComponent内部,您需要删除鼠标上的部分图像。我正在做这件事,我会很快发布答案。你应该