2012-01-02 41 views
7

Có ai biết về sự khác biệt trong hành vi kéo và thả giữa JDK1.6 và JDK1.7 không? Tôi đã gặp phải sự khác biệt (minh họa bên dưới) khi kéo và thả URL từ trình duyệt lên ứng dụng cần hỗ trợ JDK1.5, JDK1.6 và JDK1.7. Bây giờ tôi tự hỏi liệu có sự khác biệt nào khác và nếu chúng được ghi lại ở đâu đó.Kéo và thả sự khác biệt giữa JDK1.6 và JDK1.7

Hành vi khác mà tôi gặp là khi kéo và thả URL từ trình duyệt (không phải từ thanh địa chỉ mà từ trang) bằng cách nhấp và kéo URL vào ứng dụng Java. Trên JDK1.6, Transferable không hỗ trợ DataFlavor.javaFileListFlavor và trên JDK1.7 nó (mặc dù khi yêu cầu dữ liệu chuyển của nó, bạn nhận được một danh sách trống). Đoạn mã sau minh họa vấn đề. Nó mở ra một JFrame mà trên đó bạn có thể kéo và thả một URL như http://www.google.com và đó in ra cho dù nó sử dụng các hương vị danh sách tập tin hoặc URI-list hương vị

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; 
     } 
    }; 
    } 
} 

Kết quả đầu ra trên JDK 1.7.01

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

Kết quả đầu ra trên JDK1.6.0.18

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

tôi có thể dễ dàng tạo ra một cách giải quyết cho vấn đề này, nhưng tôi quan tâm nhiều hơn trong bất kỳ sự khác biệt biết thêm và/hoặc tài liệu về những khác biệt đó.

Sửa

Một số nghiên cứu thêm/googling làm cho tôi nghĩ rằng hành vi trên JDK7 là tạo ra cả URI và hương vị dữ liệu filelist và cung cấp cho họ cả trong chuyển nhượng. Các filelist sau đó chỉ chứa các URI đại diện cho một tập tin. Do đó, khi chỉ kéo và thả URL, danh sách tệp sẽ trống. Tôi không thể tìm thấy điều này trong mã nguồn JDK vì có vẻ như chuyển giao/transferdata được tạo trong mã gốc (hoặc ít nhất là mã mà tôi không tìm thấy nguồn). Trên danh sách gửi thư OpenJDK đã có một cuộc thảo luận về một số similar issue, có chứa các câu sau đây

Nếu bạn kéo danh sách tệp từ gốc sang Java, ứng dụng sẽ nhìn thấy cả danh sách URI và danh sách tệp. Nếu bạn kéo trong một danh sách URI, nó sẽ nhìn thấy một danh sách URI và nếu tất cả các URI là các tệp cũng là một danh sách tệp không trống, nếu không thì chỉ là một danh sách tệp rỗng.

Edit2

Dựa trên câu trả lời của serg.nechaev tôi thực hiện một số xét nghiệm thêm về 32/64 các hệ thống Linux chút và một số hệ thống Windows (từ XP lên Windows 7). Trên Linux với JDK7, tôi luôn nhận được dữ liệu URI, kết hợp với một hương vị filelist rỗng. Trên Windows, tôi nhận được một dataflavor URI và một dữ liệu filelist không rỗng. Có vẻ như một tệp .URL được tạo trong thư mục tạm thời, và điều này cũng được truyền trong hương vị dữ liệu filelist, không phải là trường hợp trên JDK 6.

Giải pháp trong tất cả các trường hợp này là kiểm tra dữ liệu URI đầu tiên, và sử dụng các dữ liệu danh sách tập tin hương vị như mùa thu trở lại

+1

Java 7 phải hỗ trợ chức năng bổ sung. Nếu bạn có thể làm điều gì đó trong Java 6, bạn không thể trong Java 7 nó có thể là một lỗi. Tôi sẽ viết mã để hỗ trợ Java 6 và nó cũng sẽ làm việc với Java 7. Nếu bạn đang nói rằng bạn muốn biết mọi tính năng mới của Java 7, do đó bạn quyết định xem bạn có muốn sử dụng tính năng đó hay không, bạn có thể là người đầu tiên tạo danh sách đó. Bạn có thể phải so sánh nguồn giữa phiên bản. Bản cập nhật BTW Java 6 30 có thể có một số tính năng của Java 7 được chuyển trở lại. –

+0

Vâng, như đã thấy trong đầu ra nó có thể được thực hiện cả trong Java6 và Java7. Tuy nhiên, thực tế trong java 7 tôi nhận được một danh sách tập tin cũng phá vỡ các mã trong ứng dụng của tôi, nơi mà một if - else nếu - xây dựng khác mà đi qua tất cả các hương vị dữ liệu. Vì vậy, bây giờ nó vào danh sách tập tin hương vị chi nhánh của mã, dẫn đến không nhập dữ liệu của tôi kể từ khi danh sách tập tin rỗng – Robin

Trả lời

2

Tôi nghĩ rằng sự thay đổi gây ra hành vi này là trong $ (JDK)/jre/lib/flavormap.tính:

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

Tuy nhiên, sử dụng mẫu của bạn và kéo một liên kết đến Google từ bài viết của bạn, tôi nhận được cả hai danh sách tập tin & danh sách uri trên JDK 1.7.0 trên 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/ 

Đó có thể là lỗi nền tảng dành riêng cho JDK 1.7.01, bạn có thể muốn điều tra thêm và có thể gửi lỗi cho Oracle.

+0

Tôi chưa kiểm tra trên WinXP, nhưng tôi sẽ kiểm tra nó ngày hôm nay và cho bạn biết liệu tôi có cùng một vấn đề . – Robin

Các vấn đề liên quan