Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Java программирование > Общие вопросы по Java, Java SE, Kotlin
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.11.2017, 10:10   #1
SnapeEye
Пользователь
 
Регистрация: 08.11.2014
Сообщений: 43
По умолчанию DnD: JList(object) -> JPanel

Доброго времени суток!

Хочу реализовать Drag and Drop механизм для своего приложения. Нужны захватить элемент JList, перетащить на какую-то JPanel и на это панели должна появиться панель фигуры, которую перетаскивали с JList.
Задумка такова:
Screenshot_1.jpg

Вопрос: как написать механизм для JList для передачи этой панели и для JPanel, которая будет принимать другую панель (с фигурой) и добавлять на своё поле (добавление в "drop" точку будет существенным плюсом).

В интернете куча статей с готовой кучей кода без какого-либо внятного объяснения или что-то примитивное типа текста из одного бокса в другой... Возможно кто-то поможет с реализацией или укажет на толковые ресурсы для ознакомления?

Вот что имею на данный момент: перетаскивается элемент JList, но панель на "drop" не реагирует...
Может что-то забыл добавить для JPanel?

DataFlavor из класса Figure:
Код:
public static DataFlavor figure_flavor = new DataFlavor(Figure.class, "A panel with a figure");
Конфигурация для JList:
Код:
JList list = new JList(listModel);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setDragEnabled(true);
list.setTransferHandler(new ListTH());
 
private static class ListTH extends TransferHandler
{
    @Override
    public int getSourceActions(JComponent c) {
        return TransferHandler.COPY;
    }
 
    @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 figure;
            }
        } ;
        return t;
    }
}
Конфигурация для JPanel (пока пытаюсь просто на "drop" место добавить JLabel с именем фигуры):
Код:
private class DropListener extends DropTarget
{
    private static final long serialVersionUID = 1L;
    private JPanel panel;
 
    @Override
    public synchronized void dragEnter(DropTargetDragEvent dtde)
    {
        if (dtde.isDataFlavorSupported(Figure.figure_flavor))
            dtde.acceptDrag(DnDConstants.ACTION_MOVE);
        else
            dtde.rejectDrag();
    }
 
    public DropListener(JPanel panel)
    {
        this.panel = panel;
    }
 
    @Override
    public synchronized void drop(DropTargetDropEvent de)
    {
        try
        {
            Transferable tr = de.getTransferable();
            Figure figure = (Figure) tr.getTransferData(Figure.figure_flavor);
            //Resizable res = new Resizable(figure);
            JLabel lb = new JLabel(figure.getFigureName());
            panel.add(lb);
            lb.setLocation(de.getLocation());
            de.dropComplete(true);
        }
        catch (UnsupportedFlavorException | IOException e)
        {
            e.printStackTrace();
        }
    }
}
Однако пока панель не реагирует на drag... Может кто глянет и дополнит/исправит?
action.gif
SnapeEye вне форума Ответить с цитированием
Старый 04.11.2017, 20:58   #2
SnapeEye
Пользователь
 
Регистрация: 08.11.2014
Сообщений: 43
По умолчанию

Изменил обработку для панели, которая принимает данные (drop data).
Код:
JPanel panel = new JPanel();
PanelDropTarget target = new PanelDropTarget(panel);
 
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 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;
    }
}
Однако всё ещё не работает... Хотелось бы увидеть Ваше мнение =)

P.S. в ListTH createTransferable, метод getTransferData: теперь новое возвращаемое значение:
Код:
@Override
public Object getTransferData(DataFlavor df) throws UnsupportedFlavorException, IOException
{
    return new JLabel(figure.getFigureName());
}
т.к. новый обработчик JPanel делает проверку на компонент в drag ресурсе.
SnapeEye вне форума Ответить с цитированием
Старый 05.11.2017, 00:30   #3
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Вы бы файлы выложили.
На взгляд проблема не читается, а в IDE лень возиться с бойлерплейтом
Black Fregat вне форума Ответить с цитированием
Старый 05.11.2017, 10:54   #4
SnapeEye
Пользователь
 
Регистрация: 08.11.2014
Сообщений: 43
По умолчанию

Цитата:
Вы бы файлы выложили.
Без проблем

Архив с проектом:
PainterBlock.rar

Вам будет нужен пакет "workspace" с его единым классом - там в конструкторе создается панель с обработчиками для drop операций.
Также Вам будет нужен пакет "commands" с классом PluginController - там есть метод "JList getPluginList()" и именно там формируется JList и обработчики для drag операций.

P.S. в пакете lib лежат 2 .jar файла - если вдруг будут какие-то проблемы - пишите.

С нетерпением жду Вашего ответа!
SnapeEye вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
JList Listener непонятки c вызовом метода из другого класса alekola Общие вопросы по Java, Java SE, Kotlin 1 22.11.2012 02:12
Ошибка при подключении к базе данных Object reference not set to an instance of an object. lowercase ASP.NET 1 20.11.2011 22:48
JList grimm_jow Общие вопросы по Java, Java SE, Kotlin 1 04.03.2011 12:28
JList grimm_jow Общие вопросы по Java, Java SE, Kotlin 0 11.01.2011 00:25
JPanel grimm_jow Общие вопросы по Java, Java SE, Kotlin 6 30.11.2010 18:59