【问题标题】:JLabels, that store ImageIcons, are returned back to original location when the mouse is clicked in the panel在面板中单击鼠标时,存储 ImageIcons 的 JLabels 将返回到原始位置
【发布时间】:2012-10-30 18:52:50
【问题描述】:

我已将此侦听器添加到 JLabel,并且可以完美地拖动图像,但是,只要我单击面板(在不存在 JLabel 的区域中),标签就会返回这是原来的位置。我不明白为什么会这样。请帮帮我,我已经花了几个小时来解决这个问题。谢谢!

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

【问题讨论】:

    标签: java swing jlabel imageicon drag-and-drop


    【解决方案1】:

    首先,您不是在拖动图标,而是在拖动组件本身。

    其次,您正在与包含标签组件的布局管理器作斗争。当面板失效时,标签将返回到其原始布局位置。

    尝试使用 JLayeredPane 之类的东西来放置标签

    根据反馈更新示例

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

    【讨论】:

    • 该面板的布局设置为 Null,它是一个 JTabbedPane。我所有的组件(将要移动的 JLabel)都在 JTabbedPane 的第一个选项卡上。
    • 事先知道这些信息会很方便;)。在 mouseDragged 事件中,我认为没有必要通过传输 API 导出。只需将组件设置为相对于单击点的新位置。我假设鼠标侦听器在拖动面板上,而不是单个标签上
    • 这很有帮助,想知道您是否可以在这里帮帮我:stackoverflow.com/questions/13149624/…
    【解决方案2】:

    为此,您需要在 JLabel 所在的容器上使用 null 布局,否则位置将重置为当前布局管理器放置标签的位置。

    更好的方法是使用DragLayout

    DragLayout 旨在替换空布局。它将尊重组件的位置。默认情况下,它将使用组件的首选大小来确定其大小。最后,它会自动计算出 Container 的首选尺寸。

    【讨论】:

    • 或 JDesktopPane 或 JLayerdPane
    • 嗨,我已经将 Layout 设置为 null。 rightPanel = new JTabbedPane(); rightPanel.setLayout(null); //并在选项卡式窗格的第一个选项卡中添加我的组件
    • 你们是最棒的!每次使用时我都将布局设置为 Null,我的问题得到了解决。即使我在一个位置明确将其设置为 null,但其他地方并没有将其设置为 null。谢谢。
    • @user1784190 然后不要忘记投票并接受正确答案
    猜你喜欢
    • 1970-01-01
    • 2012-05-25
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多