簡體   English   中英

拖放JDK1.6和JDK1.7之間的差異

[英]Drag and drop differences between JDK1.6 and JDK1.7

有沒有人知道JDK1.6和JDK1.7之間的拖放行為的差異? 將URL從瀏覽器拖放到需要支持JDK1.5,JDK1.6和JDK1.7的應用程序時,我遇到了不同(如下圖所示)。 我現在想知道是否存在其他差異以及是否在某處記錄了這些差異。

我遇到的不同行為是通過點擊並拖動URL到Java應用程序來拖放來自瀏覽器(而不是來自地址欄但來自頁面)的URL。 在JDK1.6上,Transferable不支持DataFlavor.javaFileListFlavor ,而且它支持JDK1.7(盡管在請求傳輸數據時會得到一個空列表)。 以下代碼說明了該問題。 它打開一個JFrame ,您可以在其上拖放像http://www.google.com這樣的URL,並打印出它是否使用文件列表風格或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

我可以輕松地為此問題創建一個解決方法,但我對這些差異的任何更多知識差異和/或文檔更感興趣。

編輯

一些進一步的調查/谷歌搜索讓我覺得JDK7上的行為是創建URI和文件列表數據的味道,並在transferable中提供它們。 然后,文件列表僅包含表示文件的URI。 因此,當只拖放URL時,文件列表為空。 我在JDK源代碼中找不到這個,因為似乎transferable / transferdata是在本機代碼中創建的(或者至少是我找不到源代碼的代碼)。 在OpenJDK郵件列表上有一個關於類似問題的討論,包含以下引用

如果將文件列表從本機拖到Java中,則應用程序會同時看到URI列表和文件列表。 如果你在URI列表中拖動,它會看到一個URI列表,如果所有URI都是非空文件列表的文件,否則只是一個空文件列表。

EDIT2

根據serg.nechaev的回答,我在32/64位Linux系統和幾個Windows系統(從XP到Windows7)上進行了一些測試。 在使用JDK7的Linux上,我總是得到URI dataflavor,並結合空文件列表的味道。 在Windows上,我獲得了URI dataflavor和非空文件列表數據風格。 似乎.URL文件是在temp目錄中創建的,並且這也在文件列表數據風格中傳遞,而JDK 6則不是這樣。

所有這些情況下的解決方案是首先檢查URI dataflavor,並使用文件列表數據flavor作為后退

我認為導致此行為的更改是在$(JDK)/jre/lib/flavormap.properties中

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

但是,使用您的示例並從您的帖子拖動鏈接到Google,我在WinXP,FireFox 8上獲得JDK 1.7.0上的文件列表和uri列表:

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提交錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM