Различия в перетаскивании между JDK1.6 и JDK1.7

Кто-нибудь знает о различиях в поведении drag-and-drop между JDK1.6 и JDK1.7? Я столкнулся с разницей (иллюстрация ниже) при перетаскивании URL из браузера в приложение, которое должно поддерживать JDK1.5, JDK1.6 и JDK1.7. Теперь мне интересно, существуют ли другие различия и задокументированы ли они где-нибудь.

Различное поведение, с которым я столкнулся, это когда я перетаскиваю URL из браузера (не из адресной строки, а со страницы), нажимая и перетаскивая URL на Java-приложение. На JDK1.6 Transferable не поддерживает DataFlavor.javaFileListFlavor, а на JDK1.7 поддерживает (хотя при запросе данных для перетаскивания получается пустой список). Следующий код иллюстрирует проблему. Он открывает JFrame, на который вы можете перетащить URL типа http://www.google.com и который выводит информацию о том, использует ли он flavor списка файлов или URI-list flavor

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.TransferHandler;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

public class DragAndDropTester {
  private static DataFlavor URI_LIST_FLAVOR = null;

  static {
    try {
      URI_LIST_FLAVOR = new DataFlavor( "text/uri-list;class=java.lang.String" );
    }
    catch ( ClassNotFoundException ignore ) {
    }
  }
  public static void main( String[] args ) {
    try {
      EventQueue.invokeAndWait( new Runnable() {
        public void run() {

          JFrame testFrame = new JFrame( "Test" );

          JPanel contents = new JPanel( new BorderLayout() );
          contents.add( new JLabel( "TestLabel" ), BorderLayout.CENTER );

          contents.setTransferHandler( createTransferHandler() );

          testFrame.getContentPane().add( contents );
          testFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
          testFrame.setSize( 200, 200 );
          testFrame.setVisible( true );
        }
      } );
    } catch ( InterruptedException e ) {
      throw new RuntimeException( e );
    } catch ( InvocationTargetException e ) {
      throw new RuntimeException( e );
    }
  }

  private static TransferHandler createTransferHandler(){
    return new TransferHandler(  ){
      @Override
      public boolean importData( JComponent comp, Transferable aTransferable ) {
        try {
          if ( aTransferable.isDataFlavorSupported( DataFlavor.javaFileListFlavor ) ) {
            System.out.println("File list flavor");
            List file_list = ( List ) aTransferable.getTransferData( DataFlavor.javaFileListFlavor );
            System.out.println( "file_list = " + file_list );
          }
              if ( URI_LIST_FLAVOR != null && aTransferable.isDataFlavorSupported( URI_LIST_FLAVOR ) ){
            System.out.println("URI list flavor");
            String uri_list = ( String ) aTransferable.getTransferData( URI_LIST_FLAVOR );
            System.out.println( "uri_list = " + uri_list );
          }
        } catch ( UnsupportedFlavorException e ) {
          throw new RuntimeException( e );
        } catch ( IOException e ) {
          throw new RuntimeException( e );
        }
        return true;
      }

      @Override
      public boolean canImport( JComponent comp, DataFlavor[] transferFlavors ) {
        return true;
      }
    };
  }
}

Результат вывода на JDK 1.7.01

File list flavor
file_list = []
URI list flavor
uri_list = http://www.google.com

Результат вывода на JDK1.6.0.18

URI list flavor
uri_list = http://www.google.com

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

Редактировать

Некоторые дальнейшие исследования/гугление заставляют меня думать, что поведение на JDK7 заключается в создании как URI, так и списка файлов и их обоих в передаваемом файле. Тогда список файлов содержит только те URI, которые представляют файл. Следовательно, если перетаскивать только URL, список файлов будет пуст. Я не могу найти это в исходном коде JDK, так как кажется, что transferable/transferdata создается в родном коде (или, по крайней мере, в коде, для которого я не нашел исходных текстов). В списке рассылки OpenJDK было обсуждение аналогичного вопроса, содержащее следующую цитату

Если вы перетаскиваете список файлов из native в Java, приложение видит и список URI, и список файлов. Если вы перетаскиваете список URI, то приложение видит список URI, а если все URI являются файлами, то и непустой список файлов, в противном случае просто пустой список файлов.

Edit2

Основываясь на ответе serg.nechaev, я провел еще несколько тестов на 32/64 битных Linux системах и нескольких Windows системах (от XP до Windows7). На Linux с JDK7 я всегда получаю URI dataflavor в сочетании с пустым файловым списком. В Windows я получаю URI dataflavor и непустой filelist data flavor. Похоже, что файл .URL создается в каталоге temp, и он также передается во флавор данных списка файлов, чего не было в JDK 6.

Решение во всех этих случаях - сначала проверять URI dataflavor, а затем использовать filelist data flavor как запасной вариант

7
задан Robin 10 January 2012 в 23:36
поделиться