Grains
Grains

Reputation: 950

Drag MyObject to JTable (DnD)

I am trying to drag MyObject to a JTable. But cant find out how.

Can I get help with any of this points?(preferably point 3)

**1.**The only good example I found was this:

Guide: http://www.bryanesmith.com/docs/drag-and-drop-java-5/ Source: http://www.bryanesmith.com/docs/drag-and-drop-java-5/DragAndDropPanelsDemo.java

Problem with this is that I am getting:

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

Any idea why?

**2.**Any hints on other good examples?

or **3.**Here is an example I put together. But it only displays String and not MyObject:

enter image description here

What I did to try make this work was to add:

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

But I had problems implementing Transferable and adding TransferHandler to MyObject. Any idea how it should look like?

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

Upvotes: 2

Views: 815

Answers (1)

kleopatra
kleopatra

Reputation: 51525

Still not sure what exactly the problem is - below is a simple custom TransferHandler that allows dragging items from a list and dropping them onto a table (one property per column). It's usage is pretty straightforward (it's in SwingX test environment because I'm lazy, just use core components and throw into a frame :)

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

A custom handler for some custom type:

/**
 * 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;
    }

}

Upvotes: 2

Related Questions