Search code examples
javaswingdrag-and-dropjscrollpanejlist

Erratic auto-scrolling in JList


I'm trying to create a JList that allows you to re-order items in the list by dragging them. This is working OK, except the auto-scrolling behavior is very jerky and erratic. When I grab an item in the list and drag it to the bottom of the list, I expect it to scroll smoothly and continuously, but what I actually get is that it scrolls a few pixels and stops. If I jiggle the mouse cursor around the edge of the JList, then it continues scrolling a few pixels at a time, but clearly this is not acceptable behavior.

Does anybody have suggestions on how to fix this?

In case it matters, I'm running Java 6 on Mac OS X 10.8.3.

import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;

public class DraggableJList {
    public static void main(String[] args) {
        EventQueue.invokeLater( new Runnable() {
            public void run() {
                int count=200;
                String[] elements = new String[count];
                for(int n=0; n<count; n++ ) {
                    elements[n] = String.valueOf( n );
                }

                JList list = new JList( elements );
                list.setDragEnabled( true ); //If I disable this line, the I get smooth scrolling, but I can't drag items to re-order them
                list.setDropMode( DropMode.INSERT );
                final TransferHandler transferHandler = new TransferHandler() {
                    @Override
                    public int getSourceActions( JComponent c ) {
                        return TransferHandler.MOVE;
                    }

                    @Override
                    protected Transferable createTransferable( JComponent c ) {
                        return new StringSelection( "Hey there" );
                    }
                };
                list.setTransferHandler( transferHandler );

                JScrollPane scrollPane = new JScrollPane( list );
                JFrame frame = new JFrame();

                JPanel borderPanel = new JPanel();
                borderPanel.add( scrollPane );
                borderPanel.setBorder( BorderFactory.createEmptyBorder( 40, 40, 40, 40 ) );
                frame.setContentPane( borderPanel );
                frame.pack();
                frame.setVisible( true );
            }
        } );
    }
}

Solution

  • Did some searching and it turns out this is a known bug:

    https://bugs.java.com/bugdatabase/view_bug?bug_id=6710705