java перемещение компонентов с помощью мыши

Я попытался сделать любой компонент перетаскиваемым, просто добавив слушателей мыши и используя функцию setLocation из java.awt.Component. Я начал с JButton, чтобы проверить, возможно ли это так, как я думал.

Вот пример кода для того, что я пытаюсь сделать:

import java.awt.*;
import javax.swing.*;

public class DragButton extends JButton{

private volatile int draggedAtX, draggedAtY;

public DragButton(String text){
    super(text);
    setDoubleBuffered(false);
    setMargin(new Insets(0, 0, 0, 0));
    setSize(25, 25);
    setPreferredSize(new Dimension(25, 25));

    addMouseListener(new MouseAdapter(){
        public void mousePressed(MouseEvent e){
            draggedAtX = e.getX() - getLocation().x;
            draggedAtY = e.getY() - getLocation().y;
        }
    });

    addMouseMotionListener(new MouseMotionAdapter(){
        public void mouseDragged(MouseEvent e){
            setLocation(e.getX() - draggedAtX, e.getY() - draggedAtY);
        }
    });
}

public static void main(String[] args){
    JFrame frame = new JFrame("DragButton");
    frame.setLayout(null);
    frame.getContentPane().add(new DragButton("1"));
    frame.getContentPane().add(new DragButton("2"));
    frame.getContentPane().add(new DragButton("3"));
    frame.setSize(300, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    }
}

Почему-то это не работает должным образом, и я не понимаю почему. Фактическое расстояние перетаскивания равно половине расстояния движения мыши, и оно мерцает вокруг этого расстояния во время перетаскивания, как будто две позиции мыши конкурируют за MouseMotionListener.

Может ли кто-нибудь помочь новичку в свинг/ауте? =) Заранее большое спасибо.

Edit:

Ок, проблема была в том, что я не знал, что событие будет повторно срабатывать при каждом наведении мыши, причем позиция будет относительной(!) к срабатывающему JComponent. Вот исправленный и работающий код:

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

public class DragButton extends JButton{

    private volatile int draggedAtX, draggedAtY;

    public DragButton(String text){
        super(text);
        setDoubleBuffered(false);
        setMargin(new Insets(0, 0, 0, 0));
        setSize(25, 25);
        setPreferredSize(new Dimension(25, 25));

        addMouseListener(new MouseAdapter(){
            public void mousePressed(MouseEvent e){
                draggedAtX = e.getX();
                draggedAtY = e.getY();
            }
        });

        addMouseMotionListener(new MouseMotionAdapter(){
            public void mouseDragged(MouseEvent e){
                setLocation(e.getX() - draggedAtX + getLocation().x,
                        e.getY() - draggedAtY + getLocation().y);
            }
        });
    }

    public static void main(String[] args){
        JFrame frame = new JFrame("DragButton");
        frame.setLayout(null);
        frame.getContentPane().add(new DragButton("1"));
        frame.getContentPane().add(new DragButton("2"));
        frame.getContentPane().add(new DragButton("3"));
        frame.setSize(300, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

Спасибо Adel за ваши усилия и mKorbel за ссылку.

14
задан Stephan 2 February 2012 в 01:09
поделиться