2010-09-27 9 views
8

Tengo una JList y quiero que el usuario pueda reordenar los elementos en la lista usando drag-n-drop (usando mi propio ListModel y ListCellRenderer, si eso hace alguna diferencia) ¿Qué objetos necesito crear y cómo puedo procesar la acción?Cómo habilitar arrastrar y soltar dentro de JList

Respuesta

1

¿Qué tal algo como esto:

DefaultListModel<String> myListModel = createStringListModel(); 
JList<String> myList = new JList<String>(myListModel); 
MyMouseAdaptor myMouseAdaptor = new MyMouseAdaptor(); 
myList.addMouseListener(myMouseAdaptor); 
myList.addMouseMotionListener(myMouseAdaptor); 

private class MyMouseAdaptor extends MouseInputAdapter { 
    private boolean mouseDragging = false; 
    private int dragSourceIndex; 

    @Override 
    public void mousePressed(MouseEvent e) { 
     dragSourceIndex = myList.getSelectedIndex(); 
    } 

    @Override 
    public void mouseReleased(MouseEvent e) { 
     if (mouseDragging) {   
      int dragTargetIndex = myList.getSelectedIndex(); 
      String dragElement = myListModel.get(dragSourceIndex); 
      myListModel.remove(dragSourceIndex); 
      myListModel.add(dragTargetIndex, dragElement); 
     } 
     mouseDragging = false; 
    } 

    @Override 
    public void mouseDragged(MouseEvent e) {    
     mouseDragging = true; 
    } 
} 

private DefaultListModel<String> createStringListModel() { 
    final String[] listElements = new String[] { "Cat", "Dog", "Cow", "Horse", "Pig", "Monkey" }; 
    DefaultListModel<String> listModel = new DefaultListModel<String>(); 
    for (String element : listElements) { 
     listModel.addElement(element); 
    } 
    return listModel; 
} 
5

Modificado Ene Taccis respuesta:

public class DndTest extends JFrame { 

    JList<String> myList; 
    DefaultListModel<String> myListModel; 

    public DndTest() { 
     myListModel = createStringListModel(); 
     myList = new JList<String>(myListModel); 
     MyMouseAdaptor myMouseAdaptor = new MyMouseAdaptor(); 
     myList.addMouseListener(myMouseAdaptor); 
     myList.addMouseMotionListener(myMouseAdaptor); 

     JPanel content = new JPanel(); 
     content.add(myList); 
     this.add(content); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.pack(); 
     this.setVisible(true); 
    } 

    private class MyMouseAdaptor extends MouseInputAdapter { 
     private boolean mouseDragging = false; 
     private int dragSourceIndex; 

     @Override 
     public void mousePressed(MouseEvent e) { 
      if (SwingUtilities.isLeftMouseButton(e)) { 
       dragSourceIndex = myList.getSelectedIndex(); 
       mouseDragging = true; 
      } 
     } 

     @Override 
     public void mouseReleased(MouseEvent e) { 
      mouseDragging = false; 
     } 

     @Override 
     public void mouseDragged(MouseEvent e) { 
      if (mouseDragging) { 
       int currentIndex = myList.locationToIndex(e.getPoint()); 
       if (currentIndex != dragSourceIndex) { 
        int dragTargetIndex = myList.getSelectedIndex(); 
        String dragElement = myListModel.get(dragSourceIndex); 
        myListModel.remove(dragSourceIndex); 
        myListModel.add(dragTargetIndex, dragElement); 
        dragSourceIndex = currentIndex; 
       } 
      } 
     } 
    } 

    private DefaultListModel<String> createStringListModel() { 
     final String[] listElements = new String[] { "Cat", "Dog", "Cow", "Horse", "Pig", "Monkey" }; 
     DefaultListModel<String> listModel = new DefaultListModel<String>(); 
     for (String element : listElements) { 
      listModel.addElement(element); 
     } 
     return listModel; 
    } 

    public static void main(String[] args) { 
     new DndTest(); 
    } 
} 
0

En el siguiente método hay un error lógico en él porque tan pronto como se suelta el botón del ratón, el arrastre tiene que ser detenido. En lenguaje sencillo, la condición IF debe ser negada simplemente

@Override 
    public void mouseReleased(MouseEvent e) { 
     if (!mouseDragging) {   
      int dragTargetIndex = myList.getSelectedIndex(); 
      String dragElement = myListModel.get(dragSourceIndex); 
      myListModel.remove(dragSourceIndex); 
      myListModel.add(dragTargetIndex, dragElement); 
     } 
     mouseDragging = false; 
    }