Das blickt ja kein schwein mehr... Ein paar Comments sind immer hilfreich...
Hab das ganze mal eben in 15min selbst gebaut, ohne irgendwas "durchzulesen" .. Einfach try&error und ein wenig Verstand.
Code:
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Transfer extends JPanel {
JPanel elementPanel = new JPanel();
JPanel dragPaintPanel = new JPanel();
JButton button = new JButton("Hallo Welt");
boolean currentlyDragging = false;
public Transfer() {
// absolutes Layout. Mit anderen Layouts wird's vermutlich wesentlich aufwendiger
this.setLayout(null);
elementPanel.setLayout(null);
elementPanel.setOpaque(true); // transparent
elementPanel.setFocusable(false); // nicht fokusierbar
dragPaintPanel.setLayout(null);
dragPaintPanel.setOpaque(true); // transparent
dragPaintPanel.setFocusable(false); // nicht fokusierbar
// beide Panels auf die gleiche Größe und Position bringen
elementPanel.setBounds(0, 0, 800, 600);
dragPaintPanel.setBounds(0, 0, 800, 600);
// Button basteln
button.setBounds(100, 100, 150, 21);
button.setName("meinButton");
// Visuelle Elemente hinzufügen
elementPanel.add(button);
dragPaintPanel.addMouseMotionListener(new MouseMotionListener(){
public void mouseDragged(MouseEvent e) {
System.out.println("Drag: "+e.getX()+"/"+e.getY());
// schauen was denn da liegt wo wir versuchen zu draggen ...
JComponent component = (JComponent) elementPanel.getComponentAt(e.getX(), e.getY());
// Erstmal nur "JButtons" akzeptieren ....
if (component instanceof JButton){
System.out.println("Verschiebe: "+component.getName());
// Die Komponente so positionieren, dasss der Mauszeiger immer in der Mitte ist
component.setLocation(e.getX()-(component.getWidth()/2), e.getY()-(component.getHeight()/2));
System.out.println(component.getName()+" now at x="+component.getBounds().x+" y="+component.getBounds().y);
}
System.out.println();
}
public void mouseMoved(MouseEvent e) {
System.out.println("Move: "+e.getX()+"/"+e.getY());
JComponent component = (JComponent) elementPanel.getComponentAt(e.getX(), e.getY());
if (component instanceof JButton){
System.out.println("... over: "+component.getName());
}
System.out.println();
}
});
// Die Einfügereihenfolge ist wichtig... Sonst ist der Button "klickbar". Aber wir wollen
// ihn ja nicht anklicken, sondern verschieben können.... Offensichtlich liegt das "zuletzt"
// eingefügte Element "unten" .. Das was "oben" liegen soll, muss also als erstes rein.
this.add(dragPaintPanel);
this.add(elementPanel);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().add(new Transfer());
frame.setSize(800,600);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Known Bugs:
* Bewegt man die Maus beim draggen zu schnell, "verlässt" man den Einzugsbereich der Komponente und man hört auf sie zu verschieben.
* Habs nicht mit mehreren Komponenten getestet. Aber es könnt in der aktuellen implementierung sehr gut sein, dass das ganz gewaltig durcheinander gerät wenn man einen Button über einen anderen hinweg zieht.
Man müsste noch was einbauen mit dem man sich merkt "was" gerade gedragged wird und von da an, bis zum loslassen der maus _nicht mehr_ prüft was "drunter" liegt, sondern exakt das weiterverschiebt was man eh gerade schon schiebt.
- Alex