将自定义对象从JList拖放到JLabel中 [英] Drag and Drop custom object from JList into JLabel

查看:84
本文介绍了将自定义对象从JList拖放到JLabel中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含自定义对象的ArrayList的JList,我正在尝试创建一个拖放到字段中。我无法理解如何在Transferable中打包和接收对象。



这是关于我已经得到的:

  import java.awt。*; 

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

public class FlightProjectInterface extends JFrame {

//创建GUI对象

private JFrame primaryFrame;
private JPanel createFlightPanel;
私人JPanel飞机

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

public FlightProjectInterface(){

//建立框架
super(创建航班);
setLayout(new FlowLayout());

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

//构建人员加载列表
DefaultListModel listModel = new DefaultListModel();
(个人: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中选择对象并从中创建一个可传输文件。使用上面的代码,对象的toString表示形式简单地粘贴在文本字段中,因此我无法从丢弃的位置提取对象数据。我如何打包对象本身并将其放入占位符,我可以从GUI引用对象本身?



理想情况下,每个都有4个字段包含一个可以删除的对象。如果人员被删除,该人员将被从列表中删除,但如果被替换,则返回列表。

解决方案

拖放可以是一个复杂的野兽,不会因冲突的信息而变得更容易。就我个人而言,我喜欢避免使用Transfer API,但我是这样的老学校。



DnD的胶水真的是 DataFlavor 。我喜欢自己滚动,使生活更容易。



在这个例子中,我使用了一个 TransferHandler ,但实际上,你真的应该有一个用于拖动和一个用于删除,特别是你应该有一个对于你想要的每个组件。



主要原因是我在我的 canImport 方法中放置了一个陷阱,如果你拖动一个 JList 所以你只能放在 JLabel 上,这是一个小黑客,可能不是最好的主意。

  public class DnDTransferableTest {

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

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

JFrame框架= 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);
}
});
}

public class TestPane扩展JPanel {

private JList list;
私人JLabel标签;

public TestPane(){

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

DefaultListModel model = new DefaultListModel(); (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());

}
}

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();
对象值= t.getTransferData(ListItemTransferable.LIST_ITEM_DATA_FLAVOR);
if(value instanceof ListItem){
组件组件= 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可移植的createTransferable(JComponent c){
可传递t = null;
if(c instanceof JList){
JList list =(JList)c;
对象值= 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);
//这里你需要决定如何处理传输的完成,
//你应该从列表中删除项目吗?
}
}

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(){
返回新的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();
}
}
}


I have a JList containing an ArrayList of custom objects and I'm trying to create a drag and drop into fields. I'm having trouble understanding how to package and receive the object in Transferable.

This is about as far as I've gotten:

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

}

Clarification: I'm having trouble taking the object selection from the JList and creating a Transferable out of it. With the code above, the toString representation of the object is simply pasted in the text field, so I'm not able to pull object data from the dropped location. How can I "package" the object itself and drop it into a placeholder that I can reference the object itself from the GUI?

Ideally, there would be 4 fields that each contains an object that can be dropped. The person would be removed from the list if they are dropped, but returned to the list if replaced.

解决方案

Drag and Drop can be a complex beast, not made any easier by the conflicting information that's available. Personally, I like to avoid the Transfer API, but I'm old school like that.

The glue to DnD really is the DataFlavor. I prefer to roll my own, makes life a lot easier.

In this example, I've used a single TransferHandler, but realistically, you really should have one for dragging and one for dropping, in particular, you should have one for each component you want to drop onto.

The main reason for this is, I put a trap in my canImport method to reject it if your dragging over a JList, so you can only drop it on the JLabel, this is a little hack and probably not the best idea.

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);
            }
        });
    }

    public class TestPane extends JPanel {

        private JList list;
        private JLabel label;

        public TestPane() {

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

            DefaultListModel model = new DefaultListModel();
            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());

        }
    }

    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) {
                JList list = (JList) 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();
        }
    }
}

这篇关于将自定义对象从JList拖放到JLabel中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆