JList Elemente anordnen

smathedark

Mitglied
Hallo,

ich versuche in einer JListe Elemente per Drag and Drop anordnen zu können.
Nun bin ich ja soweit, dass ich Elemente markieren und und zeihen kann. Was mir allerdings nicht gelingt, ist es den Index der Liste zu erfassen an dem ich das Element wieder Dropen will. Sprich wie erhalte ich den Index über dem ich die Maustaste wieder losgelassen habe.

Gruß
 
Kannst du vielleicht ein kleines lauffähiges Codebeispiel posten, mit dem man dein Problem nachvollziehen kann.

Ich habe momentan nicht ganz so im Kopf was man beim Drop alles an Objekte zur Verfügung hat.
 
Hallo,

ein laffähiges Beispiel ist schwierig, da es sich um eine recht große komplexe Software handelt. Aber ich poste hier mal den TransferHandler der für die Verarbeitung des Drag and Drop zuständig ist.
Am meisten stört mich halt das sich die Elemente der Liste über die ich beim ziehen mit der maus fahre verfärben. Also scheint irgentwo die Liste ja zu sehen über welchem Element ich mich grade mit der Maus befinde. Leiser finde ich keine möglichkeit den Index dieses Elements bei der Liste anzufragen.

Code:
package testGenerator;
import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import javax.swing.*;

import dataClasses.Module;

public class TransferHandlerTest extends TransferHandler {
    DataFlavor localArrayListFlavor, serialArrayListFlavor;
    String localArrayListType = DataFlavor.javaJVMLocalObjectMimeType +
                                ";class=java.util.ArrayList";
    TestgeneratorModel model=null;
    JList source = null;
    int[] indices = null;
    int addIndex = -1; //Location where items were added
    int addCount = 0;  //Number of items added

    public TransferHandlerTest(TestgeneratorModel model) {
    	this.model=model;
    	 try {
             localArrayListFlavor = new DataFlavor(localArrayListType);
         } catch (ClassNotFoundException e) {
             System.out.println(
              "ReportingListTransferHandler: unable to create data flavor");
         }
         serialArrayListFlavor = new DataFlavor(ArrayList.class,
                                               "ArrayList");
	}

	public boolean importData(JComponent c, Transferable t) {
        JList target = null;
        ArrayList alist = null;
        if (!canImport(c, t.getTransferDataFlavors())) {
            return false;
        }
        try {
            target = (JList)c;
            if (hasLocalArrayListFlavor(t.getTransferDataFlavors())) {
                alist = (ArrayList)t.getTransferData(localArrayListFlavor);
            } else if (hasSerialArrayListFlavor(t.getTransferDataFlavors())) {
                alist = (ArrayList)t.getTransferData(serialArrayListFlavor);
            } else {
                return false;
            }
        } catch (UnsupportedFlavorException ufe) {
            System.out.println("importData: unsupported data flavor");
            return false;
        } catch (IOException ioe) {
            System.out.println("importData: I/O exception");
            return false;
        }


        //At this point we use the same code to retrieve the data
        //locally or serially.

        //We'll drop at the current selected index.
        int index = target.getSelectedIndex();
/*
        //Prevent the user from dropping data back on itself.
        //For example, if the user is moving items #4,#5,#6 and #7 and
        //attempts to insert the items after item #5, this would
        //be problematic when removing the original items.
        //This is interpreted as dropping the same data on itself
        //and has no effect.
        if (source.equals(target)) {
            if (indices != null && index >= indices[0] - 1 &&
                  index <= indices[indices.length - 1]) {
                indices = null;
                return true;
            }
        }
        */

        ListModel listModel = (ListModel)target.getModel();
        int max = listModel.getSize();
        System.out.printf("index = %d  max = %d%n", index, max);
        if (index < 0) {
            index = max; 
        } else {
            index++;
            if (index > max) {
                index = max;
            }
        }
        addIndex = index;
        addCount = alist.size();
        for (int i=0; i < alist.size(); i++) {
            Module m=this.model.getTest().getModuleData().get(index);
            this.model.getTest().getModuleData().add(addIndex,m);
            this.model.getTest().getModuleData().remove(index);
        }
        return true;
    }

    protected void exportDone(JComponent c, Transferable data, int action) {
        if ((action == MOVE) && (indices != null)) {
          //  DefaultListModel model = (DefaultListModel)source.getModel();

            /*//If we are moving items around in the same list, we
            //need to adjust the indices accordingly since those
            //after the insertion point have moved.
            if (addCount > 0) {
                for (int i = 0; i < indices.length; i++) {
                    if (indices[i] > addIndex &&
                        indices[i] + addCount < source.getModel().getSize()) {
                        indices[i] += addCount;
                    }
                }
            }
            for (int i = indices.length -1; i >= 0; i--)
            	source.remove(indices[i]);*/
        }
        JList t=(JList)c;
        int  [] i=t.getSelectedIndices();
    
        indices = null;
        addIndex = -1;
        addCount = 0;
    }

    private boolean hasLocalArrayListFlavor(DataFlavor[] flavors) {
        if (localArrayListFlavor == null) {
            return false;
        }

        for (int i = 0; i < flavors.length; i++) {
            if (flavors[i].equals(localArrayListFlavor)) {
                return true;
            }
        }
        return false;
    }

    private boolean hasSerialArrayListFlavor(DataFlavor[] flavors) {
        if (serialArrayListFlavor == null) {
            return false;
        }

        for (int i = 0; i < flavors.length; i++) {
            if (flavors[i].equals(serialArrayListFlavor)) {
                return true;
            }
        }
        return false;
    }

    public boolean canImport(JComponent c, DataFlavor[] flavors) {
        if (hasLocalArrayListFlavor(flavors))  { return true; }
        if (hasSerialArrayListFlavor(flavors)) { return true; }
        return false;
    }

    protected Transferable createTransferable(JComponent c) {
        if (c instanceof JList) {
            source = (JList)c;
            indices = source.getSelectedIndices();
            Object[] values = source.getSelectedValues();
            if (values == null || values.length == 0) {
                return null;
            }
            ArrayList<String> alist = new ArrayList<String>(values.length);
            for (int i = 0; i < values.length; i++) {
                Object o = values[i];
                String str = o.toString();
                if (str == null) str = "";
                alist.add(str);
            }
            return new ReportingListTransferable(alist);
        }
        return null;
    }

    public int getSourceActions(JComponent c) {
        return COPY_OR_MOVE;
    }

    public class ReportingListTransferable implements Transferable {
        ArrayList data;

        public ReportingListTransferable(ArrayList alist) {
            data = alist;
        }

        public Object getTransferData(DataFlavor flavor)
                                 throws UnsupportedFlavorException {
            if (!isDataFlavorSupported(flavor)) {
                throw new UnsupportedFlavorException(flavor);
            }
            return data;
        }

        public DataFlavor[] getTransferDataFlavors() {
            return new DataFlavor[] { localArrayListFlavor,
                                      serialArrayListFlavor };
        }

        public boolean isDataFlavorSupported(DataFlavor flavor) {
            if (localArrayListFlavor.equals(flavor)) {
                return true;
            }
            if (serialArrayListFlavor.equals(flavor)) {
                return true;
            }
            return false;
        }
    }
}
 
Du hast ja die JList zur Verfügung. Probier mal ob getSelectedIndex darauf dir das richtige Ergebnis gibt.
 
Genau das ist ja das ärgerliche, wenn ich getSelectedIndex() mache gibt er mir den Index des Elements das ich grade ziehe nicht den des Elements über dem ich drope.
 
Hi,
also ich bin einen Schritt weiter. Ich habe den TransferHandler durch Listener ersetzt. Nun funktioniert es soweit das ich einen Index bekomme. Nur ist dieser Index nicht richtig. innerhalb der Liste habe ich immer den index des letzten Listenelements, ziehe ich das Element nöch höher über die Liste hinaus so wird der Index kleiner ganz oben im Rahgmen des Frames dann zu 0.
Es schein als würde der Index relativ zum ganzen Frame genommen statt innerhalb der List. Ich werde bald verrückt. Poste mal meinen neuen Code vielleciht kennt ja jemand den letzten kniff damit es endlich läuft.
Code:
package testGenerator;

import java.awt.datatransfer.StringSelection;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;

import javax.swing.DropMode;
import javax.swing.JList;

import javax.swing.ListSelectionModel;
/**
 * Diese Klasse repräsentiert eine einfache JList, die es ermöglicht,
 * ihre Elemente per Drag and Drop zu Ordnen. 
 * @author smaybaum
 *
 */
public abstract class DNDList extends JList implements DragSourceListener,DragGestureListener{
	private static final long serialVersionUID = 1L;
	DragSource ds=null;
	DragGestureRecognizer dgr=null;

	public DNDList(){
	    this.setDropMode(DropMode.ON);
	    ds = new DragSource();
	    dgr = ds.createDefaultDragGestureRecognizer(this,
	    DnDConstants.ACTION_MOVE, this);
	}

	public void dragGestureRecognized(DragGestureEvent dge) {
		    System.out.println("Drag Gesture Recognized!");
		    StringSelection transferable = new StringSelection(this.getSelectedValue().toString());
		    ds.startDrag(dge, DragSource.DefaultMoveDrop, transferable, this);
		  }

		  public void dragEnter(DragSourceDragEvent dsde) {
		    System.out.println("Drag Enter");
		  }

		  public void dragExit(DragSourceEvent dse) {
		    System.out.println("Drag Exit");
		  }

		  public void dragOver(DragSourceDragEvent dsde) {
		    System.out.println("Drag Over");
		  }

		  public void dragDropEnd(DragSourceDropEvent dsde) {
		    System.out.print("Drag Drop End: ");
		    if (dsde.getDropSuccess()) {
		      System.out.println("Succeeded"+this.locationToIndex(dsde.getLocation()));
		    } else {
		      System.out.println("Succeeded"+this.locationToIndex(dsde.getLocation()));
		    }
		  }

		  public void dropActionChanged(DragSourceDragEvent dsde) {
		    System.out.println("Drop Action Changed");
		  }
		  
		  abstract boolean performDrop();
} //Class
 
Zurück