How to redirect all console output to a Swing JTextArea/JTextPane with the right encoding?

本小妞迷上赌 提交于 2019-12-01 05:12:30
Vilmantas Baranauskas

Try this 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à");

}

}

String in java does not have an encoding - Strings are backed by a character array, and character should always be utf-16 while they are treated as strings and char values.

The encoding only comes into question when you export or import strings/chars to or from an external representation (or location). The transfer must take place using a sequence of bytes to represent the string.

I think the first solution is close, but also totally confused. First you ask java to translate the char values to their cp1252-encoded equivalent values (the 'word'for the similarily-shaped character in the cp1252 'language'). Then you create a string from this byte sequence, stating that this sequence of cp-1252 codes is in fact a sequence of utf-8 codes and should be translated to the standard in-memory representation (utf-16) from utf-8.

A string is never utf og cp1252 or anything like that - it is alsways characters. Only byte sequences are utf-8 or cp1252. If you want to translate char values to a utf-8 string you could use.

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

Actually, I think the problem lies elsewhere, probably inside the printstream and how it prints its input. You should try to avoid converting strings and chars to/from bytes, because that is always a major source of confusion and trouble. Perhaps you must override all methods in order to capture character data before conversion.

As you rightfully assume the problem is most likely in:

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

since you encode with UTF-8, characters may be encoded with more than 1 byte and thus adding each byte you read as a character won't work.

To make it work you can try writing all bytes into a ByteBuffer and using a CharsetDecoder (Charset.forName("UTF-8).newDecoder(), "UTF-8" to match the PrintStream) to convert them into characters which you add the panel.

I haven't tried it to make sure it works, but I think it is worth a try.

marcospereira

You should create the PrintStream with the right encode: http://www.j2ee.me/j2se/1.5.0/docs/api/java/io/PrintStream.html#PrintStream(java.io.File, java.lang.String)

Could you please provide more code about what are you trying to do?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!