当前位置: 首页 > 面试题库 >

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

燕刚毅
2023-03-14
问题内容

我在JLabel中有一个图像。

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

我想要以下功能。

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

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

好吧,这意味着在许多情况下,图片将被裁剪并且在视野之外。

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

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


问题答案:

这是一个基本的例子…

通过将标签划分为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;

        }

    }

}

根据反馈更新

这个例子基本上使用a 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);
            }
        }
    }
}


 类似资料:
  • 问题内容: 因此,正如标题所述,我想在鼠标拖动时移动椭圆。我先声明了椭圆并将其画出(因为我有8个椭圆,它们带有不同的颜色信息。四个是白色,另一个是红色)。我尝试做我对矩形所做的事情: 但这似乎不起作用。它给我一个错误 我有点困惑,因为我已经阅读了文档,并且Ellipse2D.Double存在这样的变量。 这是一个MCVE: 那么是否有替代算法,或者我只是在语法上缺少什么?我想知道解决方案。谢谢。

  • 我正在使用MySQL Workbench - EER模型建模数据库。现在,我想移动某些实体,这样我可以将它们包装在单独的层中,以获得更好的视觉效果。我的问题是,我不能使用“点击和拖动”技术在EER图上移动实体。此外,我想选择一些地区,围绕某些实体,并把他们在层。“选择对象”(鼠标箭头)是选定的工具。 是不是图表编辑器处于某种锁定模式?也许我按下了一些快捷键或启用/禁用了一些选项,但我找不到在EER

  • 我是硒的新手,我面临着简单任务的问题。 我试图将鼠标移动到页面中的特定区域(x,y坐标),然后单击,但没有成功。我确实阅读了文档,因为chromewebdriver,我使用了。 这是我的代码: 另一个问题。我知道有第四个参数起源,但是,我不知道我是否正确导入了它。 我也不知道如何触发点击事件,因为我没有选择任何元素。我想点击鼠标指针的最后位置。

  • 我试图在JavaFX中执行以下操作。我正在用画布在屏幕上画东西,我希望发生以下事情: 当我点击画布表面时(比如快速按下并释放):有些事情发生了 当我在画布表面拖动时(如按住并移动,然后释放):会发生其他事情 但是如果我拖动,我希望它排除单击操作,所以如果我拖动,如果我单击,会发生什么事情,而不应该发生。不幸的是,当我释放鼠标时,释放和单击事件都会启动,即使我拖动鼠标。

  • 问题内容: 我正在使用TransferHandler将数据从JPanel作为JLabel传递到JTextArea (单击左侧面板中的某处以创建要拖动的JLabel) 数据的传输工作正常,但是我还想“显示” JLabel,因为 它与鼠标指针一起被拖动。 如果您注释掉 您将看到我想要它的外观。(但当然不会传输数据)。 如何既可以进行传输又可以使JLabel跟随鼠标光标? 这是代码: 问题答案: 另一个

  • 我正在用谷歌地图在Android上做一个小项目。我有一个问题-它是可能使标记拖动与一次点击它,而不是长按后。例如:我点击标记,它改变了图标,我可以拖动它在地图的任何地方,然后再点击一次,他就不能再拖动了,并且把它的图标改回来了?(即使松开标记器,标记器也必须从第一次点击到第二次点击时始终可拖动)