2009-10-05 27 views
6

Tôi đã cố gắng chuyển hướng System.out PrintStream sang JTextPane. Điều này hoạt động tốt, ngoại trừ việc mã hóa các ký tự đặc biệt của miền địa phương. Tôi tìm thấy rất nhiều tài liệu về nó (xem ví dụ: mindprod encoding page), nhưng tôi vẫn đang chiến đấu với nó. Các câu hỏi tương tự đã được đăng trong StackOverFlow, nhưng mã hóa không được giải quyết như tôi đã thấy.Làm thế nào để chuyển hướng tất cả đầu ra bàn điều khiển đến một Swing JTextArea/JTextPane với mã hóa bên phải?

giải pháp đầu tiên:

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

giải pháp thứ hai nên sử dụng java.nio. Tôi không hiểu cách sử dụng 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 

Không có giải pháp nào hoạt động. Bất kỳ ý tưởng?

Cảm ơn trước, jgran

+0

tắt câu hỏi chủ đề: tại sao hai người dùng - jgran (OP) và jgran (người trả lời: http: //stackoverflow.com/questions/1522444/how-to-redirect- all-console-output-to-a-swing-jtextarea-jtextpane-với-the-right/1530213 # 1530213)? – akf

+0

Sai lầm của tôi ... nên có Câu hỏi thường gặp nghiêm túc hơn. Vì vậy, cùng một người dùng! –

Trả lời

5

Hãy thử mã này:

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

Cảm ơn rất nhiều vì giải pháp của bạn có thể nhanh chóng thích nghi với vấn đề của riêng tôi. Trân trọng. –

+0

Liệu 'write()' có tự động gọi là 'flush() 'không? – TheRealChx101

+0

@ chx101, write() không gọi flush() nhưng PrintStream làm cho mỗi dòng mới. Xin lưu ý rằng việc thực hiện các tuôn ra() trong ví dụ trên sử dụng bộ đệm char của 1024 - đó là không thích hợp cho việc sử dụng sản. –

0

String trong java không có mã hóa - Strings được hậu thuẫn bởi một mảng ký tự, và nhân vật nên luôn luôn utf-16 trong khi họ được đối xử như các chuỗi và giá trị char.

Mã hóa chỉ xuất hiện khi bạn xuất hoặc nhập chuỗi/ký tự vào hoặc từ đại diện bên ngoài (hoặc vị trí). Việc chuyển giao phải diễn ra bằng cách sử dụng một chuỗi các byte để biểu diễn chuỗi.

Tôi nghĩ rằng giải pháp đầu tiên là gần, nhưng cũng hoàn toàn nhầm lẫn. Trước tiên, bạn yêu cầu java dịch các giá trị char sang các giá trị tương đương được mã hóa cp1252 của chúng (từ 'cho ký tự có hình dạng tương tự trong ngôn ngữ' cp1252 '). Sau đó, bạn tạo một chuỗi từ chuỗi byte này, cho biết chuỗi mã cp-1252 này thực tế là một chuỗi mã utf-8 và phải được dịch sang biểu diễn trong bộ nhớ chuẩn (utf-16) từ utf-8.

Chuỗi không bao giờ là utf og cp1252 hoặc bất kỳ thứ gì giống như vậy - đó là các ký tự alsways. Chỉ các chuỗi byte là utf-8 hoặc cp1252. Nếu bạn muốn dịch các giá trị char thành chuỗi utf-8, bạn có thể sử dụng.

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

Thực ra, tôi nghĩ vấn đề nằm ở đâu đó, có thể là bên trong printstream và cách in đầu vào. Bạn nên cố gắng tránh chuyển đổi chuỗi và ký tự thành/từ byte, vì đó luôn là nguồn gây nhầm lẫn và rắc rối chính. Có lẽ bạn phải ghi đè tất cả các phương thức để nắm bắt dữ liệu ký tự trước khi chuyển đổi.

0

Như bạn đúng là giả định vấn đề là có khả năng nhất trong:

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

kể từ khi bạn mã hóa với UTF-8, nhân vật có thể được mã hóa với hơn 1 byte và do đó thêm mỗi byte bạn đọc như một nhân vật đoạt 't làm việc.

Để làm cho nó hoạt động, bạn có thể thử viết tất cả các byte vào một ByteBuffer và sử dụng một CharsetDecoder (Charset.forName ("UTF-8) .newDecoder()," UTF-8 "để phù hợp với PrintStream) để chuyển đổi chúng thành các ký tự mà bạn thêm bảng điều khiển

Tôi chưa thử nó để đảm bảo nó hoạt động, nhưng tôi nghĩ nó đáng để thử.

Các vấn đề liên quan