【问题标题】:Drag MyObject to JTable (DnD)将 MyObject 拖到 JTable (DnD)
【发布时间】:2013-10-15 09:28:40
【问题描述】:

我正在尝试将MyObject 拖到JTable。但不知道怎么做。

我可以就这几点获得帮助吗?(最好是第 3 点)

**1.**我发现的唯一很好的例子是:

指南:http://www.bryanesmith.com/docs/drag-and-drop-java-5/ 来源:http://www.bryanesmith.com/docs/drag-and-drop-java-5/DragAndDropPanelsDemo.java

问题是我得到了:

java.lang.ClassNotFoundException: RandomDragAndDropPanel(行:197)

知道为什么吗?

**2.**关于其他好例子的任何提示?

或**3.**这是我放在一起的一个例子。但它只显示String 而不是MyObject

我为完成这项工作所做的工作是添加:

public static DataFlavor FLAVOR = new DataFlavor(MyObject.class, "My Object");

但我遇到了问题implementing Transferable 并将TransferHandler 添加到MyObject。知道它应该是什么样子吗?

import java.awt.Color;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.DropMode;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.TransferHandler;
import javax.swing.table.DefaultTableModel;

public class FlavorTest extends JFrame {

    // FLAVOR = STRING
    private DataFlavor FLAVOR = new DataFlavor(String.class, "DataWrapper");

    public FlavorTest() {

        // CREATE TABLE
        DefaultTableModel model = getDefaultTableModel();
        JTable table = new JTable(model);
        addDragSupport(table, model);
        table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        table.setDropMode(DropMode.INSERT_ROWS);
        table.setFillsViewportHeight(true);

        // ADD TABLE AND DRAG OBJECT TO PANEL
        JPanel panel = new JPanel();
        panel.add(new MyObject("DRAG OBJECT"));
        panel.add(table);

        // ADD PANEL TO JFRAME
        this.add(panel);
        this.pack();
        this.setDefaultCloseOperation(1);
        this.setVisible(true);
    }

    // CREATE TABLE DATA
    private DefaultTableModel getDefaultTableModel() {
        String[] cols = { "a", "b", "c" };
        String[][] rows = { { "1", "2", "3" } };
        return new DefaultTableModel(rows, cols);
    }

    // SET TRANSFER HANDLER TO TABLE
    private void addDragSupport(final JTable table, final DefaultTableModel model) {
        table.setTransferHandler(new TransferHandler() {

            public boolean canImport(TransferSupport support) {
                return true;
            }

            public boolean importData(TransferSupport support) {
                JTable.DropLocation dl = (JTable.DropLocation) support.getDropLocation();
                int row = dl.getRow();
                Object data;
                try {
                    data = (Object) support.getTransferable().getTransferData(FLAVOR);
                } catch (UnsupportedFlavorException e) {
                    e.printStackTrace();
                    return false;
                } catch (IOException e) {
                    e.printStackTrace();
                    return false;
                }
                String[] rowData = data.toString().split(",");
                model.insertRow(row, rowData);
                return true;
            }
        });
    }

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

    // CONTAINS A DRAGABLE JLIST WITH A STRING
    private class MyObject extends JPanel {

        public MyObject(String text) {
            DefaultListModel<String> model = new DefaultListModel<String>();
            model.addElement(text);
            JList<String> list = new JList<String>(model);
            list.setModel(model);
            list.setDragEnabled(true);
            list.setFocusable(false);
            this.add(list);
            this.setBorder(BorderFactory.createLineBorder(Color.black));
        }
    }
}

【问题讨论】:

  • 你需要一个自定义的 TransferHandler 在你的桌子上接受你的对象——不是字符串类型的,或者是吗?重读后,不明白你在追求什么:MyObject is-a JPanel,当你把它放在JTable上会发生什么?请注意,您从不向表中添加组件..
  • 我真正想做的是将 MyObject 添加到 JTable 中。一旦它被放入 JTable 中,我希望能够调用例如 myObject.getText(),然后在 JTable 中显示此文本(或“MyObject”包含的其他数据)。

标签: java swing drag-and-drop


【解决方案1】:

仍然不确定到底是什么问题 - 下面是一个简单的自定义 TransferHandler,它允许将项目从列表中拖放到表格中(每列一个属性)。它的用法很简单(因为我比较懒,所以在SwingX测试环境下,直接用核心组件扔到一个框架里就好了:)

JXTable table = new JXTable(0, 2);
DefaultComboBoxModel persons = new DefaultComboBoxModel(
        new PersonObject[] { new PersonObject("first", "last"),
                new PersonObject("first2", "last2"),
                new PersonObject("first3", "last3"), });
JXList list = new JXList(persons);
PersonTransferHandler handler = new PersonTransferHandler();
list.setTransferHandler(handler);
list.setDragEnabled(true);
table.setTransferHandler(handler);
showWithScrollingInFrame(table, list, "custom dnd");

一些自定义类型的自定义处理程序:

/**
 * Just an example: can export Person objects from a list an
 * import to a table with two columns
 */
public static class PersonTransferHandler extends TransferHandler {

    DataFlavor personFlavor = new DataFlavor(PersonObject.class, "PersonObject");
    DataFlavor[] flavors = new DataFlavor[] {personFlavor};

    /**
     * Implemented to return true if the support can provide string values.
     */
    @Override
    public boolean canImport(TransferSupport support) {
        if (!support.isDrop()) {
            return false;
        }
        if (!(support.getComponent() instanceof JTable)) {
            return false;
        }
        return isSupportedType(support);
    }


    @Override
    public boolean importData(TransferSupport support) {
        if (!canImport(support)) {
            return false;
        }
        try {
            PersonObject person = (PersonObject) support.getTransferable().getTransferData(personFlavor);
            Object[] rowData = new Object[]{person.firstName, person.lastName};
            JTable table = (JTable) support.getComponent();
            ((DefaultTableModel) table.getModel()).addRow(rowData);
            return true;
        } catch (UnsupportedFlavorException | IOException e) {
            e.printStackTrace();
        }
        return false;
    }


    @Override
    protected Transferable createTransferable(JComponent c) {
        if (!(c instanceof JList)) return null;
        JList list = (JList) c;
        final PersonObject person = (PersonObject) list.getSelectedValue();
        Transferable t = new Transferable() {

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

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

            @Override
            public Object getTransferData(DataFlavor flavor)
                    throws UnsupportedFlavorException, IOException {
                return person;
            }

        };
        return t;
    }



    @Override
    public int getSourceActions(JComponent c) {
        return COPY;
    }


    private boolean isSupportedType(TransferSupport support) {
        DataFlavor[] flavors = support.getDataFlavors();
        for (DataFlavor dataFlavor : flavors) {
            if (dataFlavor.getRepresentationClass() == PersonObject.class) return true;
        }
        return false;
    }

}

public static class PersonObject {
    String firstName;
    String lastName;

    public PersonObject() {

    }
    /**
     * @param firstName
     * @param lastName
     */
    public PersonObject(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

}

【讨论】:

  • 效果很好!这正是我想要的(一个放在 JTable 中的自定义对象)。非常感谢!
猜你喜欢
  • 2019-11-05
  • 2017-04-15
  • 2017-05-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-17
  • 2016-03-14
相关资源
最近更新 更多