Как перенаправить весь консольный вывод в Swing JTextArea / JTextPane с правильной кодировкой? - PullRequest
6 голосов
/ 06 октября 2009

Я пытался перенаправить System.out PrintStream в JTextPane. Это прекрасно работает, за исключением кодирования специальных символов локали. Я нашел много документации об этом (см. Например, страница кодировки mindprod ), но я все еще с этим борюсь Подобные вопросы были опубликованы в StackOverFlow, но, насколько я видел, кодировка не была рассмотрена.

Первое решение:

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

Второе решение должно использовать java.nio. Я не понимаю, как использовать Charset.

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

Ни одно из решений не работает. Есть идеи?

Заранее спасибо, jgran

Ответы [ 4 ]

5 голосов
/ 08 октября 2009

Попробуйте этот код:

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 голосов
/ 06 октября 2009

Вы должны создать PrintStream с правильным кодированием: http://www.j2ee.me/j2se/1.5.0/docs/api/java/io/PrintStream.html#PrintStream(java.io.File, java.lang.String)

Не могли бы вы предоставить больше кода о том, что вы пытаетесь сделать?

0 голосов
/ 07 октября 2009

Как вы правильно предполагаете, проблема, скорее всего, в:

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

поскольку вы кодируете с помощью UTF-8, символы могут кодироваться более чем 1 байтом, и, следовательно, добавление каждого прочитанного вами байта в качестве символа не будет работать.

Чтобы это работало, вы можете попробовать записать все байты в ByteBuffer и использовать CharsetDecoder (Charset.forName ("UTF-8) .newDecoder ()," UTF-8 ", чтобы соответствовать PrintStream) для преобразования их в символы который вы добавляете панель.

Я не пробовал, чтобы убедиться, что он работает, но я думаю, что стоит попробовать.

0 голосов
/ 06 октября 2009

Строка в java не имеет кодировки - строки поддерживаются массивом символов, и символ всегда должен быть utf-16, пока они обрабатываются как строки и значения символов.

Кодировка возникает только при экспорте или импорте строк / символов в или из внешнего представления (или местоположения). Передача должна осуществляться с использованием последовательности байтов для представления строки.

Я думаю, что первое решение близко, но также полностью запутано. Сначала вы просите java перевести значения char в их эквивалентные значения в кодировке cp1252 («слово» для символа аналогичной формы в «языке» cp1252). Затем вы создаете строку из этой последовательности байтов, утверждая, что эта последовательность кодов cp-1252 на самом деле является последовательностью кодов utf-8 и должна быть переведена в стандартное представление в памяти (utf-16) из utf-8.

Строка никогда не является utf og cp1252 или чем-то подобным - это всегда символы. Только байтовые последовательности - это utf-8 или cp1252. Если вы хотите преобразовать значения char в строку utf-8, вы можете использовать.

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

На самом деле, я думаю, что проблема кроется в другом месте, возможно, в принтстриме и в том, как он печатает свой ввод. Вы должны стараться избегать преобразования строк и символов в / из байтов, потому что это всегда является основным источником путаницы и проблем. Возможно, вы должны переопределить все методы, чтобы захватить символьные данные перед преобразованием.

...