Swing delegating drop event to parent container

636 views Asked by At

I want to delegate a "drop" event of a JList to its parent (JPanel) and remove the visual feedback of dropping on JList.

What is the correct way to do this?

I am trying to create a DropTarget object and share it between the JPanel and JList, but it seems a bit hackish --- I can't figure out what DropTarget.getComponent() supposed to do and worry it may break stuff.

Can you advice the correct way to do this (in Java 6)?

EDIT: *Why I am doing this?*

I am trying to let the user to put items into groups (one JPanel + one JList = one group) --the list order will not be preserved (and cannot be preserved because of some internal data-structures) when the item is dropped on the JList.

The default visual feedback for JList is a line-like cursor hinting where it will be added. If I use the default, the user will be confused when he found the item is added to the end of list, not where the cursor have shown.

To make the visual feedback look easier, I am doing it on JPanel-level (one JPanel for one JList, some semi-transparent overlay over the list and stuff..). Naturally, dropping to that JPanel should add to the list as well. So....

2

There are 2 answers

1
kleopatra On

The visual feedback for the drop location is handled by the cell renderer. A dirty trick to remove is a custom renderer which does nothing in that respect (note that the logic is not complete, you'll probably have to handle the "real" selection case):

    ListCellRenderer renderer = new DefaultListCellRenderer() {

        @Override
        public Component getListCellRendererComponent(JList list,
                Object value, int index, boolean isSelected,
                boolean cellHasFocus) {
            super.getListCellRendererComponent(list, value, index, isSelected,
                    cellHasFocus);
            JList.DropLocation dropLocation = list.getDropLocation();
            if (dropLocation != null
                    && !dropLocation.isInsert()
                    && dropLocation.getIndex() == index) {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }
            return this;
        }

    };

That combined with a custom transferHandler which is installed both on the list and the containing panel should be very near to what you need (in its importData, add the item to the end of the list, select the new entry and scroll to it)

1
Axel Dörfler On

If you don't need to preserve the JList drag&drop handling, the easiest way to achieve this is to set its TransferHandler to null. Assuming that its parent has a TransferHandler set, it will then automatically get to handle drag&drop events.