2012-12-13 24 views
8

Mam JList zawierający ArrayList niestandardowych obiektów i próbuję utworzyć przeciągnij i upuść na pola. Mam problem ze zrozumieniem, jak spakować i odebrać obiekt w opcji Transferable.Przeciągnij i upuść niestandardowy obiekt z JList do JLabel

Jest to o ile stałam:

import java.awt.*; 

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

public class FlightProjectInterface extends JFrame{ 

    //create GUI Objects 

    private JFrame primaryFrame; 
    private JPanel createFlightPanel; 
    private JPanel aircraftLayout; 

    private JList personsJList, personsOnFlightJList; 
    private JTextField pilotLabel, coPilotLabel, backseat1Label, backseat2Label; 

    public FlightProjectInterface(){ 

     //establish frame 
     super("Create Flight"); 
     setLayout(new FlowLayout()); 

     //aircraftPanel 
     aircraftLayout = new JPanel(); 
     aircraftLayout.setLayout(new GridLayout(2,2)); 
     pilotLabel = new JTextField("Drag Pilot Here"); 

     //build person load list 
     DefaultListModel listModel = new DefaultListModel(); 
     for (Person person : Database.persons) 
      listModel.addElement(person); 

     personsJList = new JList(listModel); 
     personsJList.setVisibleRowCount(5); 
     personsJList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     personsJList.setDragEnabled(true); 

     add(new JScrollPane(personsJList)); 

     aircraftLayout.add(pilotLabel); 
     add(aircraftLayout); 

    }//end constructor 

} 

Wyjaśnienie: Mam problemy Biorąc wybór obiektu z JList i tworząc Transferable z niego. Z powyższym kodem, reprezentacja obiektu toString jest po prostu wklejana w polu tekstowym, więc nie jestem w stanie pobrać danych obiektu ze zrzuconej lokalizacji. Jak mogę "spakować" sam obiekt i umieścić go w symbolu zastępczym, który mogę odnieść do samego obiektu z GUI?

Idealnie byłoby 4 pola, z których każdy zawiera obiekt, który można upuścić. Osoba zostanie usunięta z listy, jeśli zostanie upuszczona, ale zwrócona do listy po jej zastąpieniu.

+0

* "Mam problem ze zrozumieniem, jak spakować i odebrać obiekt w Zbywalnych." * Zobacz [Przeciągnij i upuść oraz Transfer danych] (http://docs.oracle.com/javase/tutorial /uiswing/dnd/index.html) i wróć do nas, gdy podjąłeś próbę i możesz zadać konkretne pytanie. –

+0

Czytam to od kilku godzin. Mam problem z wyborem obiektu z listy JList i utworzeniem z niego możliwości przeniesienia. Z powyższym kodem, reprezentacja obiektu toString jest po prostu wklejana w polu tekstowym, więc nie jestem w stanie pobrać danych obiektu z upuszczonej lokalizacji. –

+0

'nie można znaleźć symbol symbol: zmienna Baza danych lokalizacja: klasa FlightProjectInterface' - Aby uzyskać lepszą pomoc wcześniej, opublikuj [SSCCE] (http://sscce.org/). –

Odpowiedz

15

Funkcja przeciągnij i upuść może być złożoną bestią, nie jest łatwiejsza dzięki dostępnym sprzecznym informacjom. Osobiście lubię unikać interfejsu API transferu, ale jestem tak stara.

Klej do DnD to naprawdę DataFlavor. Wolę toczyć własne, sprawia, że ​​życie jest o wiele łatwiejsze.

W tym przykładzie użyłem pojedynczego TransferHandler, ale realistycznie, naprawdę powinieneś mieć jeden do przeciągania i jeden do upuszczania, w szczególności powinieneś mieć jeden dla każdego komponentu, który chcesz upuścić.

Głównym powodem jest to, umieścić pułapkę w moim sposobie canImport odrzucić jeśli przeciąganie nad JList, więc można tylko upuść go na JLabel, to jest trochę siekać i chyba nie najlepszy pomysł .

import java.awt.BorderLayout; 
import java.awt.Component; 
import java.awt.EventQueue; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.datatransfer.DataFlavor; 
import java.awt.datatransfer.Transferable; 
import java.awt.datatransfer.UnsupportedFlavorException; 
import java.awt.dnd.DnDConstants; 
import java.io.IOException; 

import javax.swing.DefaultListModel; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JList; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.TransferHandler; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class DnDTransferableTest { 

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

    public DnDTransferableTest() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    @SuppressWarnings("serial") 
    public class TestPane extends JPanel { 

     private JList<ListItem> list; 
     private JLabel label; 

     public TestPane() { 

      list = new JList<ListItem>(); 
      list.setDragEnabled(true); 
      list.setTransferHandler(new ListTransferHandler()); 

      DefaultListModel<ListItem> model = new DefaultListModel<ListItem>(); 
      for (int index = 0; index < 10; index++) { 

       model.addElement(new ListItem("Item " + index)); 

      } 
      list.setModel(model); 

      setLayout(new GridBagLayout()); 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.gridx = 0; 
      gbc.gridy = 0; 
      gbc.weighty = 1; 
      gbc.weightx = 1; 
      gbc.fill = GridBagConstraints.BOTH; 
      add(new JScrollPane(list), gbc); 

      label = new JLabel("Drag on me..."); 
      gbc.gridx++; 
      gbc.weightx = 1; 
      gbc.fill = GridBagConstraints.NONE; 
      add(label, gbc); 

      label.setTransferHandler(new ListTransferHandler()); 

     } 
    } 

    @SuppressWarnings("serial") 
    public class ListTransferHandler extends TransferHandler { 

     @Override 
     public boolean canImport(TransferSupport support) { 
      return (support.getComponent() instanceof JLabel) && support.isDataFlavorSupported(ListItemTransferable.LIST_ITEM_DATA_FLAVOR); 
     } 

     @Override 
     public boolean importData(TransferSupport support) { 
      boolean accept = false; 
      if (canImport(support)) { 
       try { 
        Transferable t = support.getTransferable(); 
        Object value = t.getTransferData(ListItemTransferable.LIST_ITEM_DATA_FLAVOR); 
        if (value instanceof ListItem) { 
         Component component = support.getComponent(); 
         if (component instanceof JLabel) { 
          ((JLabel)component).setText(((ListItem)value).getText()); 
          accept = true; 
         } 
        } 
       } catch (Exception exp) { 
        exp.printStackTrace(); 
       } 
      } 
      return accept; 
     } 

     @Override 
     public int getSourceActions(JComponent c) { 
      return DnDConstants.ACTION_COPY_OR_MOVE; 
     } 

     @Override 
     protected Transferable createTransferable(JComponent c) { 
      Transferable t = null; 
      if (c instanceof JList) { 
       @SuppressWarnings("unchecked") 
       JList<ListItem> list = (JList<ListItem>) c; 
       Object value = list.getSelectedValue(); 
       if (value instanceof ListItem) { 
        ListItem li = (ListItem) value; 
        t = new ListItemTransferable(li); 
       } 
      } 
      return t; 
     } 

     @Override 
     protected void exportDone(JComponent source, Transferable data, int action) { 
      System.out.println("ExportDone"); 
      // Here you need to decide how to handle the completion of the transfer, 
      // should you remove the item from the list or not... 
     } 
    } 

    public static class ListItemTransferable implements Transferable { 

     public static final DataFlavor LIST_ITEM_DATA_FLAVOR = new DataFlavor(ListItem.class, "java/ListItem"); 
     private ListItem listItem; 

     public ListItemTransferable(ListItem listItem) { 
      this.listItem = listItem; 
     } 

     @Override 
     public DataFlavor[] getTransferDataFlavors() { 
      return new DataFlavor[]{LIST_ITEM_DATA_FLAVOR}; 
     } 

     @Override 
     public boolean isDataFlavorSupported(DataFlavor flavor) { 
      return flavor.equals(LIST_ITEM_DATA_FLAVOR); 
     } 

     @Override 
     public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { 

      return listItem; 

     } 
    } 

    public static class ListItem { 

     private String text; 

     public ListItem(String text) { 
      this.text = text; 
     } 

     public String getText() { 
      return text; 
     } 

     @Override 
     public String toString() { 
      return getText(); 
     } 
    } 
} 
+0

Dokładnie tego szukałem, doskonale to wyjaśniłem! Dzięki! –

+0

Masz na myśli pojedynczy 'Transferable' lub pojedynczy' TransferHandler'? – johnchen902

+0

@ johnchen902 Kto wie, co mam na myśli, myślę, że twoje prawo, brzmi jak TransferHandler – MadProgrammer