2012-01-02 14 views
7

¿Alguien sabe acerca de las diferencias en el comportamiento de arrastrar y colocar entre JDK1.6 y JDK1.7? Encontré una diferencia (ilustrada a continuación) al arrastrar y colocar una URL desde un navegador a una aplicación que necesita ser compatible con JDK1.5, JDK1.6 y JDK1.7. Ahora me pregunto si existen otras diferencias y si están documentadas en alguna parte.Arrastrar y soltar diferencias entre JDK1.6 y JDK1.7

El comportamiento diferente que encontré es cuando arrastra y suelta una URL desde un navegador (no desde la barra de direcciones sino desde la página) haciendo clic y arrastrando la URL a la aplicación Java. En JDK1.6, el Transferible no es compatible con el DataFlavor.javaFileListFlavor y en el JDK1.7 sí (aunque al solicitar sus datos de transferencia se obtiene una lista vacía). El siguiente código ilustra el problema. Se abre una JFrame donde puede arrastrar y soltar un URL como http://www.google.com y que imprime si se utiliza el sabor lista de archivos o el URI-lista sabor

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

Como resultado de salida en JDK 1.7.01

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

resultante de salida en JDK1.6.0.18

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

que puede crear fácilmente una solución para este problema, pero estoy más interesado en saber más cualquier diferencia y/o documentación sobre esas diferencias.

Editar

Algunos mayor investigación/google me hace pensar en el comportamiento JDK7 es crear tanto el URI y el sabor de datos lista de archivos y ofreciéndoles tanto en la transferible. La lista de archivos solo contiene los URI que representan un archivo. Por lo tanto, cuando solo se arrastra y suelta una URL, la lista de archivos está vacía. No puedo encontrar esto en el código fuente de JDK, ya que parece que transferible/transferdata se crea en código nativo (o al menos código para el que no encuentro las fuentes). En la lista de correo OpenJDK hubo una discusión sobre un similar issue, que contiene la siguiente cita

Si arrastra una lista de archivos de nativos en Java, la aplicación ve tanto una lista de URI y una lista de archivos. Si arrastra en una lista de URI, verá una lista de URI, y si todos los URI son archivos, también una lista de archivos no vacíos; de lo contrario, solo una lista de archivos vacía.

Edit2

Sobre la base de la respuesta de serg.nechaev he realizado algunas pruebas más en los sistemas Linux de 32/64 bits y sistema de Windows varios (que van desde XP a Windows 7). En Linux con JDK7 siempre obtengo el sabor de datos de URI, combinado con un sabor de lista de archivos vacío. En Windows, obtengo un sabor de datos URI y un sabor de datos de lista de archivos no vacío. Parece que se crea un archivo .URL en el directorio temporal, y esto también se pasa en el sabor de datos de la lista de archivos, que no fue el caso en JDK 6.

La solución en todos estos casos es verificar el URI dataflavor primero, y use el sabor de los datos de la lista de archivos como retrospectiva

+1

Java 7 debería ser compatible con funciones adicionales. Si puede hacer algo en Java 6, no es posible que en Java 7 sea un error. Escribiría el código para admitir Java 6 y también funcionará con Java 7. Si está diciendo que le gustaría conocer cada característica nueva de Java 7 para que decida si desea usar esa característica, podría ser la primera persona en crear dicha lista. Puede que tenga que comparar la fuente entre la versión. BTW Java 6 update 30 puede tener algunas de las características de Java 7 retransmitidas. –

+0

Bueno, como se ve en la salida, se puede hacer tanto en Java6 como en Java7. Sin embargo, el hecho de que en java 7 obtengo una lista de archivos también rompe el código en mi aplicación, donde es una construcción if - else if - else que pasa por todos los sabores de datos. Entonces ahora ingresa la rama de sabor de la lista de archivos del código, lo que resulta en que no se importen mis datos ya que la lista de archivos está vacía – Robin

Respuesta

2

Creo que el cambio que causó este comportamiento está en $ (JDK)/jre/lib/flavormap. propiedades:

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

Sin embargo, el uso de su muestra y arrastrando un enlace a Google de su cargo, que estoy recibiendo tanto la lista de archivos & lista de URI en JDK 1.7.0 en 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/ 

Eso podría ser un error específico de plataforma para JDK 1.7.01, es posible que desee investigar más a fondo y tal vez enviar un error a Oracle.

+0

Todavía no he comprobado en WinXP, pero lo probaré hoy y le dejaré saber si tengo el mismo problema . – Robin