Добавить в DataFlavor собственный класс (Drag and Drop Java)

399
09 февраля 2017, 00:07

Я пытаюсь добавить в dataFlavor свой класс (Item.class), чтобы передать его при помощи drag and drop

@Override
public synchronized void drop(DropTargetDropEvent dtde) {                
    DataFlavor itemFlavor = new DataFlavor(Item.class, Item.class.getSimpleName());               
    try{
        System.out.println(dtde.getTransferable().getTransferData(itemFlavor));
    }catch(UnsupportedFlavorException | IOException e){
        e.printStackTrace();
    }
}

Item.class

public class Item {
    private String classFile;
    private String imgFile;
    private String imgPath;    
    public Item(String classFile, String imgFile, String imgPath){
        this.classFile = classFile;
        this.imgFile = imgFile;
        this.imgPath = imgPath;
    }
    public String getImgFile() {
        return imgFile;
    }
    public void setImgFile(String imgFile) {
        this.imgFile = imgFile;
    }   
    public String getClassFile() {
        return classFile;
    }
    public void setClassFile(String classFile) {
        this.classFile = classFile;
    }
    public String getImgPath() {
        return imgPath;
    }
    public void setImgPath(String imgPath) {
        this.imgPath = imgPath;
    }
}

но я получаю следующее сообщение об ошибке: java.awt.datatransfer.UnsupportedFlavorException: Item

Подскажите пожалуйста, как исправить эту ошибку ?

Я использовал следующую документацию https://docs.oracle.com/javase/tutorial/uiswing/dnd/dataflavor.html

Пример, который демонстрирует проблему DND Test Project . Можете его скачать, поместить эти классы в проект и запустить.

Для того чтобы получить ошибку, перетащите объект из JTable на JLayeredPane

Answer 1

Сначала кратко напишу, как работает Drag&Drop. Есть объект DragSource, который отвечает за операцию Drag, и объект DropTarget, который отвечает за операцию Drop. Эти объекты должны быть привязаны к соответствующим компонентам. Сам перетаскиваемый объект (в твоем случае Item) инкапсулируется внутрь объекта, который реализует интерфейс Transferable. Тип перетаскиваемого объекта определяет DataFlavor.

1) Создаем класс ItemTransferable, DataFlavor засунем туда же:

public class ItemTransferable implements Transferable {
    public final static DataFlavor ITEM_FLAVOR = new DataFlavor(Item.class, Item.class.getSimpleName());
    private Item item;
    public ItemTransferable(Item item) {
        this.item = item;
    }
    @Override
    public DataFlavor[] getTransferDataFlavors() {
        return new DataFlavor[] { ITEM_FLAVOR };
    }
    @Override
    public boolean isDataFlavorSupported(DataFlavor flavor) {
        return ITEM_FLAVOR.equals(flavor);
    }
    @Override
    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
        if (flavor.equals(ITEM_FLAVOR))
            return item;
        else
            throw new UnsupportedFlavorException(flavor);
    }
}

2) Создадим Drag Listener для таблицы:

JTable table = new JTable(new DefaultTableModel(new Item[][] { { new Item("class_1", "image_1", "path_1") },
                    { new Item("class_2", "image_2", "path_2") }, { new Item("class_3", "image_3", "path_3") },
                    { new Item("class_4", "image_4", "path_4") }, { new Item("class_5", "image_5", "path_5") } },
                    new String[] { "Column Name" }));
DragSource ds = new DragSource();
ds.createDefaultDragGestureRecognizer(table, DnDConstants.ACTION_MOVE, new DragGestureListener() {
    @Override
    public void dragGestureRecognized(DragGestureEvent dge) {
        if (table.getSelectedRow() != -1) {
            Item item = (Item) table.getModel().getValueAt(table.getSelectedRow(), 0);
            dge.startDrag(null, new ItemTransferable(item));
        }
    }
});

3) В методe drop():

JLabel label = new JLabel(dtde.getTransferable().getTransferData(ItemTransferable.ITEM_FLAVOR).toString());
((DefaultTableModel) table.getModel()).removeRow(table.getSelectedRow());

Еще можно сделать через TransferHandle - это вроде более высокоурневый способ, но я никогда с этим не разбирался. Вообще, drag&drop - это адский геморрой, и я бы его избегал любыми способами.

READ ALSO
Открыть запароленный zip java

Открыть запароленный zip java

Использую следующий код для чтения и записи зип файлаАрхив запаролен, не подскажете либу или куда вписать пароль?

387
Изучение языка программирования java [требует правки]

Изучение языка программирования java [требует правки]

Добрый день! Помогите пож, как думаете Java для новичка норм будет? если ваще не программировал

309
Android&SQLite: CursorIndexOutOfBoundsException при получении одной записи по ID

Android&SQLite: CursorIndexOutOfBoundsException при получении одной записи по ID

Написал метод для получения записи по указанному id:

392
Область видимости (класс в классе)

Область видимости (класс в классе)

Есть класс, в конструкторе которого вызывается другой класс, в котором в свою очередь есть публичный геттер, возвращающий значение поля

278