Перетащите различия между JDK1.6 и JDK1.7 - PullRequest
7 голосов
/ 02 января 2012

Кто-нибудь знает о различиях в поведении перетаскивания между 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, и распечатывает, использует ли он список файлов или URI-список

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> file_list = ( List<File> ) 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

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

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

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

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

Edit2

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

Решением во всех этих случаях является проверкасначала для URI dataflavor, а в качестве отката используйте вариант данных списка файлов

1 Ответ

2 голосов
/ 10 января 2012

Я думаю, что изменение, вызвавшее это поведение, находится в $ (JDK) /jre/lib/flavormap.properties:

http://hg.openjdk.java.net/jdk7/hotspot-gc/jdk/diff/fd5bf5955e37/src/windows/lib/flavormap.properties

Однако, используя ваш пример и перетаскивая ссылку на Google из вашего поста, я получаю как список файлов, так и список uri на JDK 1.7.0 на WinXP, FireFox 8:

File list flavor
file_list = [C:\DOCUME~1\SERGN\LOCALS~1\Temp\httpwww.google.com.URL]
URI list flavor
uri_list = http://www.google.com/

Это может быть ошибка платформы JDK 1.7.01 для конкретной платформы, вы можете захотеть исследовать ее дальше и, возможно, отправить ошибку в Oracle.

...