Установить пользовательский курсор при перетаскивании внешнего файла в приложение Swing - PullRequest
7 голосов
/ 17 января 2012

У меня есть приложение Swing, в которое я хотел бы импортировать внешний файл, перетаскивая внешний файл из проводника Windows в приложение.У меня этот базовый функционал работает.Однако я хотел бы изменить значок курсора по умолчанию для перетаскивания в соответствующий курсору приложения.Я не смог изменить курсор, видимый для пользователя, пока нажата клавиша мыши и удерживается над приложением.Я видел примеры этой работы, если операция перетаскивания находится в одном приложении Swing.Я пытался сделать это, используя DragGestureListener и DragSource безрезультатно.Кажется, что эти методы не вызываются, если источник перетаскивания не находится в пределах колебания.Можно ли изменить курсор перетаскивания при перетаскивании внешнего файла в приложение Swing?

См. Этот упрощенный пример:

public class DnDTemplate extends JFrame {

private static final long serialVersionUID = 1L;
private JComponent thePane = null;
private Cursor dropCursor = null;

public DnDTemplate() {
    super( "Drop File Here" );

    thePane = (JComponent) getContentPane();
    thePane.setTransferHandler( new DndTransferHandler() );

    ImageIcon imageIcon = new ImageIcon( "drop_here.gif" );
    Image image = imageIcon.getImage();     
    BufferedImage bufferedImage = new BufferedImage( 16, 16, BufferedImage.TYPE_INT_ARGB );
    Graphics graphics = bufferedImage.getGraphics();
    graphics.drawImage( image, 0, 0, null );
    dropCursor = Toolkit.getDefaultToolkit().createCustomCursor( bufferedImage, new Point( 16, 16 ), "drop cursor" );

    setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    setSize( 300, 300 );
}

public static void main( String[] args ) {
    new DnDTemplate().setVisible( true );
}

class DndTransferHandler extends TransferHandler {

    private static final long serialVersionUID = 1L;

    @Override
    public boolean canImport( TransferHandler.TransferSupport info ) {
        // This gets called repeatedly while dragged file is over frame
        if ( !info.isDataFlavorSupported( DataFlavor.javaFileListFlavor ) ) {
            return false;
        }
        // Even though this method is called at the appropriate time, 
        // setting the cursor here is of no consequence
        info.getComponent().setCursor( dropCursor );

        return true;
    }

    @Override
    public boolean importData( TransferHandler.TransferSupport info ) {
        // this gets called when file is dropped
        if ( !info.isDrop() ) {
            return false;
        }

        Transferable transferable = info.getTransferable();
        String importFileName = null;
        try {
            List<File> fileList = (List<File>) transferable.getTransferData( DataFlavor.javaFileListFlavor );
            Iterator<File> iterator = fileList.iterator();
            while ( iterator.hasNext() ) {
                File f = iterator.next();
                importFileName = f.getAbsolutePath();
            }
            info.getComponent().setCursor( dropCursor );
            thePane.setCursor( dropCursor );

        } catch ( Exception e ) {
            return false;
        }

        System.out.println( "Importing " + importFileName );
        // Return the cursor back to the default
        thePane.setCursor( Cursor.getPredefinedCursor( Cursor.DEFAULT_CURSOR ) );
        return true;
    }

}

}

1 Ответ

1 голос
/ 17 января 2012

Отказ от ответственности: это должен был быть комментарий, а не ответ, но он слишком длинный, чтобы уместиться в комментариях.Я удалю этот ответ, если он совершенно неправильный

Я не проверял это, но, глядя на API TransferHandler, я бы посоветовал взглянуть на TransferHandler#getDragImage метод.

В документации немного неясно, используется ли это изображение, когда перетаскивание инициируется из компонента, для которого установлен TransferHandler, или также используется, когда перетаскивание инициируется изза пределами приложения, и курсор появляется над компонентом, для которого установлен TransferHandler.Я нашел пример , который, кажется, предполагает, что это, безусловно, работает в Java-приложении, но все еще не дает понять, что перетаскивание происходит из внешнего приложения

Идентификатор ошибки 4816922 предлагает использовать TransferHandler#getVisualRepresentation, но неясно, исправлена ​​ли уже ошибка.

...