0

このリスナーを 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;
    }
}
4

2 に答える 2

2

まず、アイコンをドラッグするのではなく、コンポーネント自体をドラッグします。

次に、ラベル コンポーネントを含むレイアウト マネージャーと戦っています。パネルが無効化されるたびに、ラベルは元のレイアウト位置に戻されます。

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);
            }
        }
    }
}
于 2012-10-30T19:07:05.110 に答える
1

nullこれを機能させるには、 が配置されているコンテナーでレイアウトを使用する必要がありますJLabel。そうしないと、現在のレイアウト マネージャーがラベルを配置する位置に位置がリセットされます。

より良いアプローチは、DragLayoutを使用することです。

DragLayout は、null レイアウトを置き換えるように設計されました。コンポーネントの位置を尊重します。デフォルトでは、コンポーネントの優先サイズを使用してそのサイズを決定します。最後に、コンテナの推奨サイズが自動的に計算されます。

于 2012-10-30T19:05:31.237 に答える