Тема: DnD: JList(object) -> JPanel
Доброго дня!
Хочу зробити Drag and Drop систему для свого додатку. Треба захватити елемент JList, вкинути в якусь JPanel та на цiй панелi повинна з'явитись JLabel з текстом елементу, який захватували з JList.
Задумка такова:
Питання: як написать механiзм для JList щоб передачи цiй панелi та для JPanel, яка буде приймати JLabel з текстом елементу, що був вибран в JList (додати в "drop" точку буде великим плюсом).
В интернетi куча статей з готовим кодом без будь-якого нормального пояснення чи щось примитивне типа текста з одного бокса в iнший... Може хтось поможе реалiзувати чи вкаже на нормальнi ресурси для вивчення?
Ось що намагався робити: drag елементу з JList, однак панель на "drop" не реагувала...
Може щось забув додати для JPanel чи для JList?
DataFlavor для перевiрки з класу Figure:
public static DataFlavor figure_flavor = new DataFlavor(JLabel.class, null);
JPanel:
JPanel panel = new JPanel();
PanelTH th = new PanelTH(panel);
panel.setTransferHandler(th);
PanelDropTarget target = new PanelDropTarget(panel);
private class PanelTH extends TransferHandler
{
JPanel panel;
public PanelTH(JPanel panel)
{
this.panel = panel;
}
public boolean canImport(TransferHandler.TransferSupport info)
{
if (!info.isDrop())
{
return false;
}
// we only import Strings
if (!info.isDataFlavorSupported(DataFlavor.stringFlavor))
{
return false;
}
return true;
}
public boolean importData(TransferHandler.TransferSupport info)
{
// if we can't handle the import, say so
if (!canImport(info))
{
return false;
}
// fetch the data and bail if this fails
JLabel data;
try
{
data = (JLabel) info.getTransferable().getTransferData(Figure.figure_flavor);
}
catch (UnsupportedFlavorException e)
{
return false;
}
catch (IOException e)
{
return false;
}
panel.add(data);
panel.validate();
return true;
}
}
public class PanelDropTarget implements DropTargetListener
{
protected JPanel pane;
protected DropTarget dropTarget;
protected boolean acceptableType; // Indicates whether data is acceptable
protected DataFlavor targetFlavor; // Flavor to use for transfer
public PanelDropTarget(JPanel pane)
{
this.pane = pane;
// Create the DropTarget and register
// it with the JPanel.
dropTarget = new DropTarget(pane, DnDConstants.ACTION_COPY_OR_MOVE,
this, true, null);
}
// Implementation of the DropTargetListener interface
public void dragEnter(DropTargetDragEvent dtde)
{
// Get the type of object being transferred and determine
// whether it is appropriate.
checkTransferType(dtde);
// Accept or reject the drag.
acceptOrRejectDrag(dtde);
}
public void dragExit(DropTargetEvent dte)
{}
public void dragOver(DropTargetDragEvent dtde)
{
// Accept or reject the drag
acceptOrRejectDrag(dtde);
}
public void dropActionChanged(DropTargetDragEvent dtde)
{
// Accept or reject the drag
acceptOrRejectDrag(dtde);
}
public void drop(DropTargetDropEvent dtde)
{
// Check the drop action
if ((dtde.getDropAction() & DnDConstants.ACTION_COPY_OR_MOVE) != 0)
{
// Accept the drop and get the transfer data
dtde.acceptDrop(dtde.getDropAction());
Transferable transferable = dtde.getTransferable();
try
{
boolean result = dropComponent(transferable);
dtde.dropComplete(result);
}
catch (Exception e)
{
dtde.dropComplete(false);
}
}
else
{
dtde.rejectDrop();
}
}
// Internal methods start here
protected boolean acceptOrRejectDrag(DropTargetDragEvent dtde)
{
int dropAction = dtde.getDropAction();
int sourceActions = dtde.getSourceActions();
boolean acceptedDrag = false;
// Reject if the object being transferred
// or the operations available are not acceptable.
if (!acceptableType || (sourceActions & DnDConstants.ACTION_COPY_OR_MOVE) == 0)
{
dtde.rejectDrag();
}
else if ((dropAction & DnDConstants.ACTION_COPY_OR_MOVE) == 0)
{
// Not offering copy or move - suggest a copy
dtde.acceptDrag(DnDConstants.ACTION_COPY);
acceptedDrag = true;
}
else
{
// Offering an acceptable operation: accept
dtde.acceptDrag(dropAction);
acceptedDrag = true;
}
return acceptedDrag;
}
protected void checkTransferType(DropTargetDragEvent dtde)
{
// Only accept a flavor that returns a Component
acceptableType = false;
DataFlavor[] fl = dtde.getCurrentDataFlavors();
for (int i = 0; i < fl.length; i++)
{
Class dataClass = fl[i].getRepresentationClass();
if (Component.class.isAssignableFrom(dataClass))
{
// This flavor returns a Component - accept it.
targetFlavor = fl[i];
acceptableType = true;
break;
}
}
}
protected boolean dropComponent(Transferable transferable) throws IOException, UnsupportedFlavorException
{
Object o = transferable.getTransferData(targetFlavor);
if (o instanceof Component)
{
pane.add((Component) o);
pane.validate();
return true;
}
return false;
}
}
JList:
JList list = new JList(listModel);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); // Selection mode
list.setDragEnabled(true);
list.setTransferHandler(new ListTH());
private static class ListTH extends TransferHandler
{
@Override
public int getSourceActions(JComponent c)
{
return TransferHandler.COPY_OR_MOVE;
}
@Override
protected Transferable createTransferable(JComponent source)
{
JList sourceList = (JList) source;
Figure figure = (Figure) sourceList.getSelectedValue();
Transferable t = new Transferable()
{
@Override
public boolean isDataFlavorSupported(DataFlavor df)
{
for (DataFlavor current : getTransferDataFlavors())
if (current.equals(df))
return true;
return false;
}
@Override
public DataFlavor[] getTransferDataFlavors()
{
return new DataFlavor[]{Figure.figure_flavor};
}
@Override
public Object getTransferData(DataFlavor df) throws UnsupportedFlavorException, IOException
{
return new JLabel(figure.getFigureName());
}
} ;
return t;
}
}
Розраховую на Ваш свiжий погляд! Буду радий будь-якiй допомозi в вирiшеннi цього питання!
P.S. завантажую також проект.
JList - пакет commands - класс PluginController - метод getPluginList().
JPanel - пакет workspace, класс Workspace, конструктор