2012-12-13 4 views
8

カスタムオブジェクトのArrayListを含むJListがあり、ドラッグ&ドロップをフィールドに作成しようとしています。 Transferableでオブジェクトをパッケージ化して受け取る方法を理解できません。JListからJLabelにカスタムオブジェクトをドラッグアンドドロップ

これを約限り私が得ているようです:

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 

} 

明確化:私は悩みのJListからオブジェクトの選択を取って、それのうちのTransferableを作成することです。上のコードでは、オブジェクトのtoString表現がテキストフィールドに貼り付けられているため、ドロップされた場所からオブジェクトデータを取得することはできません。オブジェクト自体を「パッケージ化」して、オブジェクト自体をGUIから参照できるプレースホルダにドロップするにはどうすればよいですか?

理想的には、それぞれドロップ可能なオブジェクトを含む4つのフィールドがあります。削除された人物はリストから削除されますが、置き換えられた場合はリストに戻されます。

+0

*「Transferableでオブジェクトをパッケージ化して受け取る方法がわかりません」* [ドラッグアンドドロップとデータ転送](http://docs.oracle.com/javase/tutorial)を参照してください。 /uiswing/dnd/index.html)&あなたが試みをしたときに私たちに戻ってきて、特定の質問をすることができます。 –

+0

私は今数時間それを読んできました。私は、JListからオブジェクトの選択を受け取り、転送可能なものを作成するのに問題があります。上記のコードでは、オブジェクトのtoString表現がテキストフィールドに貼り付けられているため、ドロップされた場所からオブジェクトデータを取得することはできません。 –

+0

'シンボルを見つけることができません シンボル:変数データベース 場所:class FlightProjectInterface' - すぐに役立つように、[SSCCE](http://sscce.org/)を投稿してください。 –

答えて

15

ドラッグアンドドロップは複雑なビーストになる可能性があり、競合する情報があれば簡単には作成できません。個人的に、私はTransfer APIを避けたいですが、私はそのような古い学校です。

DnDへの接着剤は実際にDataFlavorです。私は自分自身を転がすことを好む、人生をもっと簡単にする。

この例では、1つのTransferHandlerを使用しましたが、現実的には、ドラッグするコンポーネントとドロップするコンポーネントが必要です。特に、ドロップするコンポーネントごとに1つずつ選択する必要があります。

この主な理由は、あなたがJListを超えるドラッグする場合、私はあなただけJLabel上にドロップすることができますので、これはおそらく最高のアイデアではありません少しハックであり、それを拒否するために私canImportの方法でトラップを入れて、あります。

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

これはまさに私が探していたもので、完全に説明されました!ありがとう! –

+0

単一の「Transferable」または単一の「TransferHandler」を意味しますか? – johnchen902

+0

@ johnchen902私は、あなたの権利は、TransferHandlerのように聞こえると思います。 – MadProgrammer

関連する問題