2012-12-13 13 views
8

Ho una JList contenente una lista di oggetti personalizzati e sto cercando di creare un trascinamento nei campi. Ho difficoltà a capire come confezionare e ricevere l'oggetto in Trasferibile.Trascina e rilascia oggetto personalizzato da JList a JLabel

Questo è quanto di quanto ho ottenuto:

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 

} 

Precisazione: Sto avendo difficoltà a prendere la selezione degli oggetti dal JList e creando un trasferibile fuori di esso. Con il codice sopra, la rappresentazione toString dell'oggetto viene semplicemente incollata nel campo di testo, quindi non sono in grado di estrarre i dati oggetto dalla posizione abbandonata. Come posso "impacchettare" l'oggetto stesso e rilasciarlo in un segnaposto che posso fare riferimento all'oggetto stesso dalla GUI?

Idealmente, ci sarebbero 4 campi che contengono ciascuno un oggetto che può essere eliminato. La persona verrebbe rimossa dalla lista se fosse stata rilasciata, ma sarebbe ritornata alla lista se fosse stata sostituita.

+0

* "Sto avendo difficoltà a capire come pacchetto e ricevere l'oggetto in valori." * Vedere la [Drag and Drop e trasferimento dati] (http://docs.oracle.com/javase/tutorial /uiswing/dnd/index.html) e torna da noi quando hai fatto un tentativo e puoi fare una domanda specifica. –

+0

L'ho letto da alcune ore. Ho difficoltà a prendere la selezione degli oggetti da JList e creare un trasferibile da esso. Con il codice sopra, la rappresentazione toString dell'oggetto viene semplicemente incollata nel campo di testo, quindi non sono in grado di catturare i dati oggetto dalla posizione abbandonata. –

+0

'impossibile trovare il simbolo simbolo: variabile Database posizione: class FlightProjectInterface' - Per un aiuto migliore, pubblicare un [SSCCE] (http://sscce.org/). –

risposta

15

Il trascinamento può essere una bestia complessa, non semplificata dalle informazioni in conflitto disponibili. Personalmente, mi piace evitare l'API di trasferimento, ma sono una vecchia scuola del genere.

La colla a DnD è davvero la DataFlavor. Preferisco rotolare da solo, rende la vita molto più facile.

In questo esempio, ho utilizzato un singolo TransferHandler, ma realisticamente, dovresti averne uno per il trascinamento e uno per il rilascio, in particolare, dovresti averne uno per ogni componente su cui vuoi cadere.

La ragione principale di questo è, ho messo una trappola nel mio metodo canImport per rifiutarla se il vostro trascinando nel corso di un JList, quindi si può solo cadere sul JLabel, questo è un piccolo hack e probabilmente non l'idea migliore .

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

Questo è esattamente quello che stavo cercando, spiegato perfettamente! Grazie! –

+0

Vuoi dire singolo 'trasferibile' o singolo' TransferHandler'? – johnchen902

+0

@ johnchen902 Chissà cosa intendo, penso che hai ragione, suona come TransferHandler – MadProgrammer

Problemi correlati