2013-02-10 6 views
14

Mam dziwny problem podczas wklejania HTML z Firefoxa do aplikacji Java6 (tylko!) Na Linuksie. Oto minimalne przykład:Java Clipboard: Wklej HTML z Firefoksa na Linuksie

import java.awt.Toolkit; 
import java.awt.datatransfer.Clipboard; 
import java.awt.datatransfer.DataFlavor; 
import java.awt.datatransfer.Transferable; 
import java.io.Reader; 
import java.nio.ByteBuffer; 

class ClipboardPrinter { 
    public static void main(String args[]) throws Exception 
    { 
     Clipboard systemClipboard = Toolkit.getDefaultToolkit() 
       .getSystemClipboard(); 
     Transferable transferData = systemClipboard.getContents(null); 
     if (transferData == null) { 
      System.out.println("no content"); 
      return; 
     } 

//  final DataFlavor htmlFlavorString = new DataFlavor("text/html;class=java.lang.String"); 
//  String html = (String)transferData.getTransferData(htmlFlavorString); 
//  System.out.println("html = '" + html + "'"); 

     final DataFlavor htmlFlavor = new DataFlavor("text/html;class=java.nio.ByteBuffer;charset=US-ASCII"); 
     if (!transferData.isDataFlavorSupported(htmlFlavor)) { 
      System.out.println("no text/html reader content"); 
      return; 
     } 

     ByteBuffer bb = (ByteBuffer)transferData.getTransferData(htmlFlavor); 
     byte[] bytes = bb.array(); 
     for (byte b: bytes) 
     { 
      System.out.format("%02x", b); 
     } 
     System.out.println(); 
     final int cutoff = 2; 
     byte[] bytes2 = new byte[bytes.length - cutoff]; 
     for (int i = cutoff; i < bytes.length; i++) 
      bytes2[i-cutoff] = bytes[i]; 
     final String htmlContent = new String(bytes2, "UTF-16LE"); 


     System.out.println("htmlContent = '" + htmlContent + "'"); 
    } 
} 

Najpierw próbowałem użyć new DataFlavor("text/html;class=java.lang.String"), (kod wypowiedziało się w powyższym fragmencie), ale powoduje to bezużyteczny String z 2 znaków o wartości 65533 na początku (i to nie pomaga , aby odciąć te dwa znaki).

Następny użyłem smak danych ByteBuffer z charset=US-ASCII (użyłem ASCII celowo!): charset=UTF-16LE (lub UTF-16 lub UTF-16BE) nie działa w wszystkich. Przy powyższym rozwiązaniu charset=US-ASCII (wraz z new String(bytes2, "UTF-16LE")), 7-bitowe znaki działają (ale np. Umlauty nie wykonują pracy , zamiast tego drukowane jest "?").

Odciąłem dwa bajty, ponieważ wydaje się, że są dwie bomy na początku (nie , czy może być coś innego)?

uzyskać podobny wynik z aromatem danych z charset=UTF-8 i odcięcia = 6 (dwa trzy-bajtowy „znaków zamiennych” 0xEFBFBD w początku i umlaut zakodowanej postaci dwóch błędnych znaków). W obu przypadkach użyłem new String(bytes2, "UTF-16LE").

Czy macie jakieś sugestie, jak:

  • obsługuje znaków spoza ASCII w tym roztworze (lub znaleźć lepsze rozwiązanie)?
  • określić, czy jest to kodowanie UTF-16LE czy UTF-16BE?

Dziękujemy! Wszelkie wskazówki są mile widziane!

BTW: Oto obsługiwane smaki danych na moim systemie (Linux) (od):

[java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.Reader] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.lang.String] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.nio.CharBuffer] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=[C] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.InputStream;charset=UTF-16] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.nio.ByteBuffer;charset=UTF-16] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=[B;charset=UTF-16] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.InputStream;charset=UTF-8] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.nio.ByteBuffer;charset=UTF-8] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=[B;charset=UTF-8] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.InputStream;charset=UTF-16BE] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.nio.ByteBuffer;charset=UTF-16BE] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=[B;charset=UTF-16BE] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.InputStream;charset=UTF-16LE] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.nio.ByteBuffer;charset=UTF-16LE] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=[B;charset=UTF-16LE] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.InputStream;charset=ISO-8859-1] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.nio.ByteBuffer;charset=ISO-8859-1] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=[B;charset=ISO-8859-1] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.io.InputStream;charset=US-ASCII] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=java.nio.ByteBuffer;charset=US-ASCII] 
java.awt.datatransfer.DataFlavor[mimetype=text/html;representationclass=[B;charset=US-ASCII] 
java.awt.datatransfer.DataFlavor[mimetype=application/x-java-serialized-object;representationclass=java.lang.String] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.Reader] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.lang.String] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.CharBuffer] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[C] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=unicode] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=UTF-16] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=UTF-16] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=UTF-8] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=UTF-8] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=UTF-8] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=UTF-16BE] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=UTF-16BE] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=UTF-16BE] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=UTF-16LE] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=UTF-16LE] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=UTF-16LE] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=ISO-8859-1] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=ISO-8859-1] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=ISO-8859-1] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.io.InputStream;charset=US-ASCII] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=java.nio.ByteBuffer;charset=US-ASCII] 
java.awt.datatransfer.DataFlavor[mimetype=text/plain;representationclass=[B;charset=US-ASCII] 
java.awt.datatransfer.DataFlavor[mimetype=text/x-moz-url-priv;representationclass=java.io.InputStream] 
java.awt.datatransfer.DataFlavor[mimetype=text/_moz_htmlinfo;representationclass=java.io.InputStream] 
java.awt.datatransfer.DataFlavor[mimetype=text/_moz_htmlcontext;representationclass=java.io.InputStream] 
java.awt.datatransfer.DataFlavor[mimetype=text/x-moz-url-priv;representationclass=java.nio.ByteBuffer] 
java.awt.datatransfer.DataFlavor[mimetype=text/_moz_htmlinfo;representationclass=java.nio.ByteBuffer] 
java.awt.datatransfer.DataFlavor[mimetype=text/_moz_htmlcontext;representationclass=java.nio.ByteBuffer] 
java.awt.datatransfer.DataFlavor[mimetype=text/x-moz-url-priv;representationclass=[B] 
java.awt.datatransfer.DataFlavor[mimetype=text/_moz_htmlinfo;representationclass=[B] 
java.awt.datatransfer.DataFlavor[mimetype=text/_moz_htmlcontext;representationclass=[B]] 
+0

możliwe duplikat [Java Drag and Drop Tekst poprzez DropTargetListener] (http://stackoverflow.com/questions/7305628/java-drag-and-drop-text -via-droptargetlistener) –

Odpowiedz

0

Java 6 is not supported any more. Więc pytanie jest przestarzały.

+0

Problem nadal występuje w Java7. W Javie8 jest jeszcze gorzej: kiedy wklejasz HTML z Firefoksa, powstaje śmieci (zamiast zwykłego tekstu jak w Java7). –

1

Wierzę, że problem jest związany z faktem, że on read from clipboard as US-ASCII, a następnie konwertować do Unicode i spodziewać się pozostawienia niemieckich umlaut w stanie nienaruszonym. Ponieważ US-ASCII jest 7-bitowym zestawem znaków, niemieckie umlauty nie są uwzględniane i już zostały utracone po przeczytaniu schowka jako US-ASCII.

public class CharsetDemo { 
    public static void main(String[] args) throws Exception { 
     byte[] bytes; 

     // convert the German umlaut to bytes in US-ASCII charset 
     bytes = "ö".getBytes("US-ASCII"); 
     System.out.println("US-ASCII"); 
     System.out.println("bytes : " + asHexString(bytes)); 
     System.out.println("string: " + new String(bytes, "US-ASCII")); 
     System.out.println(); 

     // create a unicode string from the US-ASCII bytes 
     String utf8String = new String(bytes, "UTF-8"); 
     bytes = utf8String.getBytes("UTF-8"); 
     System.out.println("UTF-8"); 
     System.out.println("bytes : " + asHexString(bytes)); 
     System.out.println("string: " + utf8String); 
     System.out.println(); 

     // convert the German umlaut to bytes in ISO-8859-1 charset 
     bytes = "ö".getBytes("ISO-8859-1"); 
     System.out.println("ISO 8859-1"); 
     System.out.println("bytes : " + asHexString(bytes)); 
     System.out.println("string: " + new String(bytes, "ISO-8859-1")); 
     System.out.println(); 

     // create a unicode string from the ISO-8859-1 bytes 
     utf8String = new String(bytes, "UTF-8"); 
     bytes = utf8String.getBytes("UTF-8"); 
     System.out.println("UTF-8"); 
     System.out.println("bytes : " + asHexString(bytes)); 
     System.out.println("string: " + utf8String); 
     System.out.println(); 

     // bytes of the "REPLACEMET CHARACTER" 
     System.out.println("replacement character bytes: " 
      + asHexString("\uFFFD".getBytes("UTF-8"))); 

    } 

    static String asHexString(byte[] bytes) { 
     StringBuilder sb = new StringBuilder(); 
     for (byte b : bytes) { 
      sb.append(String.format("%X ", b)); 
     } 
     return sb.toString(); 
    } 
} 

wyjście

US-ASCII 
bytes : 3F 
string: ? <--- the question mark represents here the "REPLACEMENT CHARACTER" 

UTF-8 
bytes : 3F 
string: ? 

ISO 8859-1 
bytes : F6 
string: ö 

UTF-8 
bytes : EF BF BD <-- the "REPLACEMENT CHARACTER", as "F6" is not a valid UTF-8 codepoint 
string: � 

replacement character bytes: EF BF BD 
+0

Dzięki za odpowiedź. Zgadzam się, że żądanie ASCII przy dopuszczeniu 8bit znaków nie ma sensu.Jednak to nie rozwiązuje problemu ze schowkiem powyżej. –

Powiązane problemy