拖放JDK1.6和JDK1.7之间的差异 [英] Drag and drop differences between JDK1.6 and JDK1.7

查看:133
本文介绍了拖放JDK1.6和JDK1.7之间的差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有人知道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 );
}
});
} 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);
列表<文件> 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);
}
返回true;
}

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

JDK 1.7.01的结果输出

 文件列表flavor 
file_list = []
URI列表flavor
uri_list = http:// www。 google.com

JDK1.6.0.18的结果输出

  URI列表flavor 
uri_list = http://www.google.com

我可以轻松地为此问题创建一个解决方法,但是我对这些差异的任何更多的知识差异和/或文档感兴趣。



修改



进一步的调查/搜索使我认为JDK7的行为是创建URI和文件列表数据的风格,提供他们在可转让。然后,文件列表只包含表示文件的URI。因此,当只拖放一个URL时,文件列表是空的。我在JDK源代码中找不到这个,因为它似乎是以本机代码创建的可传输/ transferdata(或者至少是找不到源的代码)。在OpenJDK邮件列表中,有一个关于类似问题的讨论,包含以下引用


如果将文件列表从本机拖动到Java中,则应用程序会看到URI列表和一个文件列表。如果你拖拽一个URI列表,它会看到一个URI列表,如果所有的URI都是一个非空的文件列表,否则只是一个空的文件列表。


Edit2



根据答案的serg.nechaev我在32/64位Linux系统和几个Windows系统(从XP到Windows7)上进行了一些测试。在使用JDK7的Linux上,我总是获得URI数据风格,并结合空的文件列表风格。在Windows上,我得到一个URI数据文件和一个非空的文件列表数据。似乎在temp dir中创建了一个 .URL 文件,这也是在文件列表数据风格中传递的,JDK 6并不是这样。 p>

所有这些情况下的解决方案是首先检查URI数据风格,并使用文件列表数据风格作为回退

解决方案

我认为导致此行为的更改是在 $(JDK)/jre/lib/flavormap.properties 中:



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



但是,使用您的示例并从您的帖子中拖动到Google的链接,我获得了文件列表和WinXP上的JDK 1.7.0上的uri列表,FireFox 8:

 文件列表flavor 
file_list = [C:\\ \\ DOCUME〜1\SERGN\LOCALS〜1\Temp\httpwww.google.com.URL]
URI列表flavor
uri_list = http://www.google.com/

这可能是针对JDK 1.7.01的特定于平台的错误,您可能需要进一步调查向Oracle提交错误。


Does anybody know about differences in the drag-and-drop behavior between JDK1.6 and JDK1.7 ? I encountered a difference (illustrated below) when drag-and-dropping an URL from a browser onto an application which needs to support JDK1.5, JDK1.6 and JDK1.7 . I am now wondering whether other differences exists and if they are documented somewhere.

The different behavior I encountered is when drag-and-drop an URL from a browser (not from the address bar but from the page) by click-and-drag the URL onto the Java application. On JDK1.6, the Transferable does not support the DataFlavor.javaFileListFlavor and on JDK1.7 it does (although when requesting for its transfer data you get an empty list). The following code illustrates the issue. It opens a JFrame on which you can drag-and-drop an URL like http://www.google.com and which prints out whether it uses the file list flavor or the 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> 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;
      }
    };
  }
}

Resulting output on JDK 1.7.01

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

Resulting output on JDK1.6.0.18

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

I can easily create a workaround for this issue, but I am more interested in any more know differences and/or documentation about those differences.

Edit

Some further investigation/googling makes me think the behavior on JDK7 is to create both the URI and filelist data flavor and offering them both in the transferable. The filelist then only contains the URI's which represent a file. Hence when only drag-and-dropping an URL, the file list is empty. I cannot find this in the JDK source code as it seems the transferable/transferdata is created in native code (or at least code for which I do not find the sources). On the OpenJDK mailing list there was a discussion about a similar issue, containing the following quote

If you drag a file list from native into Java, the application sees both a URI list and a file list. If you drag in a URI list it sees a URI list, and if all URIs are files also a non-empty file list, otherwise just an empty file list.

Edit2

Based on the answer of serg.nechaev I performed some more tests on 32/64 bit Linux systems and several Windows system (ranging from XP to Windows7). On Linux with JDK7 I always get the URI dataflavor, combined with an empty filelist flavor. On Windows, I get a URI dataflavor and a non-empty filelist data flavor. It seems a .URL file gets created in the temp dir, and this is passed in the filelist data flavor as well, which wasn't the case on JDK 6.

Solution in all these cases is to check for the URI dataflavor first, and use the file list data flavor as fall-back

解决方案

I think the change that caused this behaviour is in $(JDK)/jre/lib/flavormap.properties:

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

However, using your sample and dragging a link to Google from your post, I am getting both file list & uri list on JDK 1.7.0 on 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/

That could be a platform-specific bug for JDK 1.7.01, you might want to investigate it further and maybe submit a bug to Oracle.

这篇关于拖放JDK1.6和JDK1.7之间的差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆