2009-10-05 5 views
6

J'ai essayé de rediriger System.out PrintStream vers un JTextPane. Cela fonctionne correctement, sauf pour l'encodage des caractères régionaux spéciaux. J'ai trouvé beaucoup de documentation à ce sujet (voir par exemple mindprod encoding page), mais je me bats toujours avec. Des questions similaires ont été postées dans StackOverFlow, mais l'encodage n'a pas été traité autant que je l'ai vu.Comment rediriger toutes les sorties de la console vers un Swing JTextArea/JTextPane avec le bon encodage?

Première solution:

String sUtf = new String(s.getBytes("cp1252"),"UTF-8"); 

Deuxième solution devrait utiliser java.nio. Je ne comprends pas comment utiliser le jeu de caractères.

Charset defaultCharset = Charset.defaultCharset() ; 
byte[] b = s.getBytes(); 
Charset cs = Charset.forName("UTF-8"); 
ByteBuffer bb = ByteBuffer.wrap(b); 
CharBuffer cb = cs.decode(bb); 
String stringUtf = cb.toString(); 
myTextPane.text = stringUtf 

Aucune solution ne fonctionne. Une idée?

Merci à l'avance, jgran

+0

hors question le sujet: pourquoi les deux utilisateurs - jgran (OP) et jgran (answerer: http: //stackoverflow.com/questions/1522444/how-to-redirect- all-console-output-to-a-swing-jtextarea-jtextpane-avec-le-droit/1530213 # 1530213)? – akf

+0

Mon erreur ... devrait avoir la FAQ plus sérieusement. Donc, le même utilisateur! –

Répondre

5

Essayez ce code:

public class MyOutputStream extends OutputStream { 

private PipedOutputStream out = new PipedOutputStream(); 
private Reader reader; 

public MyOutputStream() throws IOException { 
    PipedInputStream in = new PipedInputStream(out); 
    reader = new InputStreamReader(in, "UTF-8"); 
} 

public void write(int i) throws IOException { 
    out.write(i); 
} 

public void write(byte[] bytes, int i, int i1) throws IOException { 
    out.write(bytes, i, i1); 
} 

public void flush() throws IOException { 
    if (reader.ready()) { 
     char[] chars = new char[1024]; 
     int n = reader.read(chars); 

     // this is your text 
     String txt = new String(chars, 0, n); 

     // write to System.err in this example 
     System.err.print(txt); 
    } 
} 

public static void main(String[] args) throws IOException { 

    PrintStream out = new PrintStream(new MyOutputStream(), true, "UTF-8"); 

    System.setOut(out); 

    System.out.println("café résumé voilà"); 

} 

} 
+0

Merci beaucoup pour votre solution qui pourrait être rapidement adaptée à mon propre problème. Cordialement. –

+0

Est-ce que 'write()' appelle automatiquement 'flush()'? – TheRealChx101

+0

@ chx101, write() n'appelle pas flush() mais PrintStream le fait pour chaque nouvelle ligne. Veuillez noter que l'implémentation de flush() dans l'exemple ci-dessus utilise un tampon char de 1024 - ce qui ne convient pas à l'utilisation de prod. –

0

chaîne en Java ne dispose pas d'un codage - Les chaînes sont soutenues par un tableau de caractères, et le caractère doivent toujours être utf-16 alors qu'ils sont traités comme des chaînes et les valeurs char.

L'encodage n'est remis en question que lorsque vous exportez ou importez des chaînes/caractères vers ou depuis une représentation externe (ou un emplacement). Le transfert doit avoir lieu en utilisant une séquence d'octets pour représenter la chaîne.

Je pense que la première solution est proche, mais aussi totalement confuse. D'abord, vous demandez à java de traduire les valeurs char en leurs valeurs équivalentes codées en cp1252 (le «mot» pour le caractère de forme similaire dans le langage 'cp1252'). Ensuite, vous créez une chaîne à partir de cette séquence d'octets, indiquant que cette séquence de codes cp-1252 est en fait une séquence de codes utf-8 et devrait être traduite dans la représentation standard en mémoire (utf-16) de utf-8.

Une chaîne n'est jamais utf og cp1252 ou quelque chose comme ça - ce sont toujours des caractères. Seules les séquences d'octets sont utf-8 ou cp1252. Si vous voulez traduire les valeurs char en une chaîne utf-8, vous pouvez utiliser.

byte[] utfs = myString.getBytes("UTF-8"); 

En fait, je pense que le problème se situe ailleurs, probablement dans le flux d'impression et comment il imprime son entrée. Vous devriez essayer d'éviter de convertir des chaînes et des caractères en octets, car c'est toujours une source majeure de confusion et de problèmes. Vous devez peut-être remplacer toutes les méthodes afin de capturer les données de caractères avant la conversion.

0

Comme vous assumez à juste titre le problème est le plus probable:

String s = Character.toString((char)i); 

puisque vous encodez avec UTF-8, les caractères peuvent être codés avec plus de 1 octet et ajoutant ainsi chaque octet que vous lisez comme un personnage gagné ne fonctionne pas. Pour le faire fonctionner, vous pouvez essayer d'écrire tous les octets dans un ByteBuffer et en utilisant un CharsetDecoder (Charset.forName ("UTF-8) .newDecoder()," UTF-8 "pour correspondre à PrintStream) pour les convertir en les caractères que vous ajoutez le panneau

Je ne l'ai pas essayé pour m'assurer que cela fonctionne, mais je pense que cela vaut la peine d'essayer.

Questions connexes