2012-12-13 24 views
8

Tôi có một JList chứa ArrayList của các đối tượng tùy chỉnh và tôi đang cố tạo một kéo và thả vào các trường. Tôi gặp sự cố khi hiểu cách gói và nhận đối tượng trong Có thể chuyển.Kéo và thả đối tượng tùy chỉnh từ JList vào JLabel

này là về như xa như tôi đã nhận:

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 

} 

Làm rõ: Tôi đang gặp rắc rối lấy lựa chọn đối tượng từ JList và tạo ra một thể chuyển nhượng ra khỏi nó. Với đoạn mã trên, biểu diễn toString của đối tượng chỉ được dán vào trường văn bản, vì vậy tôi không thể kéo dữ liệu đối tượng từ vị trí bị bỏ. Làm thế nào tôi có thể "gói" các đối tượng chính nó và thả nó vào một giữ chỗ mà tôi có thể tham khảo các đối tượng chính nó từ GUI?

Lý tưởng nhất, sẽ có 4 trường mà mỗi trường chứa một đối tượng có thể bị xóa. Người đó sẽ bị xóa khỏi danh sách nếu họ bị bỏ, nhưng quay trở lại danh sách nếu được thay thế.

+0

* "Tôi đang gặp khó khăn khi hiểu cách gói và nhận đối tượng trong Có thể chuyển nhượng." * Xem phần [Kéo và thả và truyền dữ liệu] (http://docs.oracle.com/javase/tutorial) /uiswing/dnd/index.html) và quay lại với chúng tôi khi bạn đã cố gắng và có thể đặt một câu hỏi cụ thể. –

+0

Tôi đã đọc nó vài giờ rồi. Tôi đang gặp khó khăn khi lựa chọn đối tượng từ JList và tạo ra một chuyển đổi từ nó. Với đoạn mã trên, biểu diễn toString của đối tượng chỉ được dán vào trường văn bản, vì vậy tôi không thể lấy dữ liệu đối tượng từ vị trí bị bỏ. –

+0

'không thể tìm thấy biểu tượng biểu tượng: biến Cơ sở dữ liệu vị trí: lớp FlightProjectInterface' - Để được trợ giúp tốt hơn sớm hơn, hãy đăng [SSCCE] (http://sscce.org/). –

Trả lời

15

Kéo và thả có thể là một con thú phức tạp, không dễ dàng hơn bởi thông tin xung đột có sẵn. Cá nhân, tôi muốn tránh các API chuyển giao, nhưng tôi là trường học cũ như thế.

Keo dán cho DnD thực sự là DataFlavor. Tôi thích để cuộn của riêng tôi, làm cho cuộc sống dễ dàng hơn nhiều. Trong ví dụ này, tôi đã sử dụng một đơn TransferHandler, nhưng thực tế, bạn thực sự cần phải có một để kéo và một cho thả, đặc biệt, bạn nên có một cho mỗi thành phần bạn muốn thả vào.

Lý do chính là, tôi đặt bẫy trong phương pháp canImport của mình để từ chối nếu bạn kéo trên JList, vì vậy bạn chỉ có thể thả nó trên JLabel, đây là một chút hack và có lẽ không phải là ý tưởng hay nhất .

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

Đây chính xác là những gì tôi đang tìm kiếm, được giải thích một cách hoàn hảo! Cảm ơn! –

+0

Bạn có nghĩa là duy nhất 'Transferable' hoặc đơn' TransferHandler'? – johnchen902

+0

@ johnchen902 Ai biết được ý tôi là gì, tôi nghĩ quyền của bạn, có vẻ như TransferHandler – MadProgrammer

Các vấn đề liên quan