# drag&drop bild verschieben



## shanxp (9. Jun 2006)

hi an alle,

Ich möchte  mehere Bilder mit hilfe von drag & drop funktion  verschieben.
Also nicht da verscheiben wo die maus gerad ist sondern ich habe  4 X 4 rechtecke gezeichnet und
die bilder sind da drin angebracht. mit der maus möchte ich z.B von einem rechteck zu einem anderen bewegen
wie geht es?
ich habe zwar ein beispiel auf Sun seite gefunden.aber damit komme ich leider nicht klar.Das sind 4 dateien 
Ich brauch nur einen Anstoß ,wie man z.B ein Bild verschiebt zu einem anderen Rechteck.

danke


----------



## André Uhres (10. Jun 2006)

shanxp hat gesagt.:
			
		

> ..ich habe  4 X 4 rechtecke gezeichnet und
> die bilder sind da drin angebracht. mit der maus möchte ich z.B von einem rechteck zu einem anderen bewegen
> ..


Du hast also 4 Zeilen mit je 4 Bildern und du willst diese 16 Bilder in eine andere Reihenfolge bringen, 
indem du ein Bild nach dem anderen verschiebst. Hab ich das so richtig verstanden?


----------



## Guest (10. Jun 2006)

Ja genau . Es soll nicht nur  freibewegbar sein sondern auch in das  rechteck  reinpassen.
ich meine wenn man ein bild mit der maus zieht  zu einem rechteck dann soll das bild  dahingezogen werden.

danke im voraus


----------



## shanxp (10. Jun 2006)

ups die obere Antwort ist von mir leider vergessen Namen einzutragen


----------



## André Uhres (10. Jun 2006)

shanxp hat gesagt.:
			
		

> ..wenn man ein bild mit der maus zieht  zu einem rechteck dann soll das bild  dahingezogen werden...


Hier ist ein möglicher Lösungsansatz:

Ich nehme mal an die Bilder sind in Dateien gespeichert, z.B. als ".jpg"

Du könntest dann erstmal eine Liste der Bilder anlegen (Pfade zu den Bilddateien)
und eine Methode schreiben die die Bilder in der Reihenfolge anzeigt wie sie in der Liste stehen. 

Die Bilder kannst du als kleinere JPanels in einem grossen JPanel (bilderContainer) anzeigen. 
Dem bilderContainer fügst du dann einen MouseListener und einen MouseMotionListener hinzu.

Bei mousePressed machst du: bilderContainer.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)) 
und speicherst die Referenz vom selectedBildPanel = (JPanel)((JPanel)evt.getSource()).getComponentAt(evt.getPoint());

Bei mouseDragged setzt du einfach einen boolean: moveMode = true;

Bei mouseReleased:

```
if( moveMode ){
            move(evt);
        }
        bilderContainer.setCursor(Cursor.getDefaultCursor());
        moveMode = false;
```
In der move(..)-Methode guckst du an welchen Positionen die beiden BildPanels liegen (panelFrom, panelTo).
Das kannst du machen indem du die components vom bilderContainer einfach durchläufst:

```
Component[] components = bilderContainer.getComponents();
        JPanel panelFrom = selectedBildPanel;
        JPanel panelTo = (JPanel)((JPanel)evt.getSource()).getComponentAt(evt.getPoint());
        int positionFrom=0;
        int positionTo=0;
        for( int i=0; i<components.length; i++ ){
            if( components[i] == panelFrom ){
                positionFrom=i;
            }
            if( components[i] == panelTo ){
                positionTo=i;
            }
        }
```
In deiner Liste verschiebst du dann das Bild von positionFrom nach positionTo 
und brauchst dann nur noch die schon erwähnte Methode aufzurufen die die Bilder 
in der Reihenfolge anzeigt wie sie in der Liste stehen.


----------



## shanxp (10. Jun 2006)

vielen dank !! probier ich aus


----------



## André Uhres (11. Jun 2006)

Wenn du willst, kannst du mit Toolkit#createCustomCursor(..) den Mauszeiger bei mouseDragged in ein 
Abbild des zu verschiebenden JPanels verwandeln:

```
private Cursor myPointer;
...
//In mousePressed:
        bilderContainer.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
        buildMyPointer(((JPanel)evt.getSource()).getComponentAt(evt.getPoint()));
...
//In mouseDragged:
        bilderContainer.setCursor(myPointer);
...
    private void buildMyPointer(Component component){
        BufferedImage image = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics g = image.getGraphics();
        g.setColor(component.getBackground());
        g.fillRect(0, 0,  image.getWidth(), image.getHeight());
        component.print(g);
        g.dispose();
        Toolkit tk = Toolkit.getDefaultToolkit();
        myPointer= tk.createCustomCursor(image, new Point(10,10), "myPointer");
    }
```


----------



## shanxp (11. Jun 2006)

hi danke !
eine Frage  braucht man keinen TransferHandler ?  :?: 
weil ich habe im Quellcode von sun TranserHandler gefunden

hier ist ein Auszug 


```
public void mouseDragged(MouseEvent e) {
        //Don't bother to drag if the component displays no image.
        if (image == null) return;

        if (firstMouseEvent != null) {
            e.consume();

            //If they are holding down the control key, COPY rather than MOVE
            int ctrlMask = InputEvent.CTRL_DOWN_MASK;
            int action = ((e.getModifiersEx() & ctrlMask) == ctrlMask) ?
                  TransferHandler.COPY : TransferHandler.MOVE;

            int dx = Math.abs(e.getX() - firstMouseEvent.getX());
            int dy = Math.abs(e.getY() - firstMouseEvent.getY());
            //Arbitrarily define a 5-pixel shift as the
            //official beginning of a drag.
            if (dx > 5 || dy > 5) {
                //This is a drag, not a click.
                JComponent c = (JComponent)e.getSource();
                TransferHandler handler = c.getTransferHandler();
                //Tell the transfer handler to initiate the drag.
                handler.exportAsDrag(c, firstMouseEvent, action);
                firstMouseEvent = null;
            }
        }
```


----------



## André Uhres (11. Jun 2006)

shanxp hat gesagt.:
			
		

> ..braucht man keinen TransferHandler..


In diesem Lösungsansatz kommen wir ohne ihn aus.


----------



## Guest (16. Jun 2006)

Hi 
ich bin gerad am programmieren
wie kann man Bilder in JPanels einfügen ?
ich versuch mit folgendem Code   aber ohne Erfolg


> public void init()
> {
> setLayout(null) ;
> bilderContainer	= new JPanel() ;
> ...


----------



## shanxp (16. Jun 2006)

ich habe wieder vergessen namen einzutragen sorry !


----------



## André Uhres (17. Jun 2006)

shanxp hat gesagt.:
			
		

> ..wie kann man Bilder in JPanels einfügen ?..




```
//package applets; 
/* 
* MovePicture.java 
*/ 
import java.awt.*; 
import java.awt.event.*; 
import java.awt.image.*; 
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.URL; 
import java.util.*; 
import java.util.List; 
import javax.imageio.ImageIO; 
import javax.swing.*; 
public class MovePicture extends JApplet { 
    private JPanel selectedBildPanel; 
    private boolean moveMode; 
    private int count;
    public void init() { 
        System.out.println("BITTE WARTEN.."); 
        add(new BilderContainer()); 
        System.out.println("OK"); 
    } 
    class BilderContainer extends JPanel implements MouseListener, MouseMotionListener{ 
        private List<Bild> bilderListe; 
        private Cursor myPointer; 
        public BilderContainer(){ 
            addMouseListener(this); 
            addMouseMotionListener(this); 
            setLayout(new GridLayout(4, 4)); 
            bilderListe = new ArrayList<Bild>(); 
            for (int i = 0; i < 8; i++) { 
                bilderListe.add(new Bild("http://www.nzz.ch/images/wetter/radargross.jpg")); 
                bilderListe.add(new Bild("http://images.thetimes.co.uk/TGD/picture/0,,223788,00.jpg")); 
            } 
            bilderAnzeigen(); 
        } 
        public void mouseClicked(MouseEvent evt) {        } 
        public void mousePressed(MouseEvent evt) { 
            setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); 
            buildMyPointer(((JPanel)evt.getSource()).getComponentAt(evt.getPoint())); 
            selectedBildPanel = (JPanel) ((JPanel)evt.getSource()).getComponentAt(evt.getPoint()); 
        } 
        public void mouseReleased(MouseEvent evt) { 
            if( moveMode ) move(evt); 
            setCursor(Cursor.getDefaultCursor()); 
            moveMode = false; 
        } 
        public void mouseEntered(MouseEvent evt) {        } 
        public void mouseExited(MouseEvent evt) {        } 
        public void mouseDragged(MouseEvent evt) { 
            setCursor(myPointer); 
            moveMode = true; 
        } 
        public void mouseMoved(MouseEvent evt) {        } 
        private void move(MouseEvent evt){ 
            Component[] components = getComponents(); 
            JPanel panelFrom = selectedBildPanel; 
            JPanel panelTo = (JPanel)((JPanel)evt.getSource()).getComponentAt(evt.getPoint()); 
            int positionFrom=0; 
            int positionTo=0; 
            for( int i=0; i<components.length; i++ ){ 
                if( components[i] == panelFrom ) positionFrom=i; 
                if( components[i] == panelTo )   positionTo=i; 
            } 
            Bild bild = bilderListe.get(positionFrom); 
            bilderListe.remove(positionFrom); 
            bilderListe.add(positionTo, bild); 
            bilderAnzeigen(); 
        } 
        private void bilderAnzeigen(){ 
            removeAll(); 
            for (Bild bild : bilderListe) add(bild); 
            validate(); 
        } 
        private void buildMyPointer(Component component){ 
            BufferedImage image = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_RGB); 
            Graphics g = image.getGraphics(); 
            g.setColor(component.getBackground()); 
            g.fillRect(0, 0,  image.getWidth(), image.getHeight()); 
            component.print(g); 
            g.dispose(); 
            Toolkit tk = Toolkit.getDefaultToolkit(); 
            myPointer= tk.createCustomCursor(image, new Point(10,10), "myPointer"); 
        } 
    } 
    class Bild extends JPanel{ 
        public Bild(String pfad){ 
            System.out.println(++count);
            try{ 
                URL url = new URL(pfad); 
                image = ImageIO.read(url); 
            }catch(Exception ex){ 
                ex.printStackTrace(); 
            } 
        } 
        public void paintComponent(final Graphics g) { 
            super.paintComponent(g); 
            g.drawImage(image,0,0,null); 
        } 
        private BufferedImage image; 
    } 
}
```


----------



## shanxp (17. Jun 2006)

hi dankee erstmal !



			
				André Uhres hat gesagt.:
			
		

> for (Bild bild : bilderListe) add(bild);
> was bedeutet diese schleife  noch nie gesehn


  :roll:  :roll:


----------



## André Uhres (17. Jun 2006)

shanxp hat gesagt.:
			
		

> ..for (Bild bild : bilderListe) add(bild);
> was bedeutet diese schleife  noch nie gesehn..


Seit Java 1.5 gibt's den "foreach loop". 
Der richtige Gebrauch hängt aber von der Benutzung der sogenannten generics ab. 

So kann man eine Liste bauen und durchlaufen: 


```
List<String> names = new ArrayList<String>();
names.add("a");
names.add("b");
names.add("c");

for (String name: names)
   System.out.println(name.charAt(0));
```

Du bindest die ArrayList an eine Klasse, hier die String-Klasse. 
Du bindest auch die List Referenz an die String Klasse. 
Dadurch beschränkst du dich darauf nur String Objekte zu der Liste hinzuzufügen. 
Wenn du ein Date Objekt zu der names collection hinzufügen willst, wird der Compiler es nicht zulassen. 
Wenn du Objekte ausliest brauchst du nicht zu casten. 
Du kannst die Liste durchlaufen mit dem foreach loop: 


```
for (String name: names)
```

Das liest sich so: "für jeden String name in names". 
Bei jedem Schleifendurchgang, gibt Java das nächste Objekt der Liste an die lokale Referenzvariable "name". 
Diese Referenzvariable musst du als String deklarieren - dem Typ an den du die names collection gebunden hast
und brauchst dann nicht mehr zu casten.


----------



## shanxp (17. Jun 2006)

vielen dank  gut zu wissen
bedanke mich herzlich für ihre Antworten


----------

