1

My application has a console where all the system's printstream content is rerouted to.

My application will also output special characters, specifically other languages (asian languages, Russian, Arabic, etc)

I'm using a JTextArea as the console out:

    consoleOutput = new JTextArea(1, 50);

    DefaultCaret caret = (DefaultCaret) consoleOutput.getCaret();
    caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);

    Font font = new Font("Consolas", Font.PLAIN, 12);
    consoleOutput.setFont(font);

    JScrollPane scrollPane = new JScrollPane(consoleOutput);
    this.add(scrollPane, BorderLayout.CENTER);


    //CHANGE OUTPUT TO THIS CONSOLE
    PrintStream out = new PrintStream(new TextAreaOutput(consoleOutput));

    System.setOut(out);
    System.setErr(out);

And this class to rerout the printstream:

public class TextAreaOutput extends OutputStream {
    JTextArea outputConsole;

    public TextAreaOutput(JTextArea outputConsole) {
        this.outputConsole = outputConsole;
    }

    @Override
    public void write(int b) throws IOException {
        outputConsole.append( String.valueOf( ( char )b ) );
    }
}

This works and the printstream prints to this jtextarea. However, I have encoding issues. Special characters like ▒, █, .نت, 览, etc do not render correctly. Some might be hardcoded into source files (I'm using UTF-8), but some might be extracted from the web with selenium webdriver.

Andrio
  • 1,852
  • 2
  • 25
  • 54
  • 2
    Unicode characters are more than 1 byte long. In UTF-8, each character may be represented by 1 to 6 bytes. So your `write` method won't work. You may want to research UTF-8 and devise a better method. – RealSkeptic Oct 01 '15 at 14:04
  • 2
    `Font font = new Font("Consolas", Font.PLAIN, 12);` Does this font support the relevant character sets? – Andrew Thompson Oct 01 '15 at 14:04
  • @AndrewThompson You're right, the font doesn't seem to support the special characters, but another problem is that the write method doesn't work correctly with UTF-8, per the other comment. – Andrio Oct 01 '15 at 14:19
  • @RealSkeptic I see, that makes sense that this write method won't work correctly with the UTF-8 – Andrio Oct 01 '15 at 14:19
  • *"..but another problem.."* For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). – Andrew Thompson Oct 03 '15 at 04:29

1 Answers1

2
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.Date;
import javax.swing.*;

public class TextAreaOutputStreamTest {
  private final JTextArea consoleOutput = new JTextArea();
  private final JTextField textField = new JTextField();

  public JComponent makeUI() {
    try {
      OutputStream os = new TextAreaOutputStream(consoleOutput);
      System.setOut(new PrintStream(os, true, "UTF-8"));
    } catch (IOException ex) {
      ex.printStackTrace();
    }
    Box box = Box.createHorizontalBox();
    box.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    box.add(Box.createHorizontalGlue());
    box.add(textField);
    box.add(Box.createHorizontalStrut(5));
    box.add(new JButton(new AbstractAction("Enter") {
      @Override public void actionPerformed(ActionEvent e) {
        String s = new Date().toString();
        System.out.println(s + "\n    " + textField.getText());
      }
    }));
    consoleOutput.setEditable(false);

    JPanel p = new JPanel(new BorderLayout());
    p.add(new JScrollPane(consoleOutput));
    p.add(box, BorderLayout.SOUTH);
    return p;
  }
  public static void main(String... args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.getContentPane().add(new TextAreaOutputStreamTest().makeUI());
    f.setSize(320, 240);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}

class TextAreaOutputStream extends OutputStream {
  private final ByteArrayOutputStream buf = new ByteArrayOutputStream();
  private final JTextArea consoleOutput;
  public TextAreaOutputStream(JTextArea consoleOutput) {
    super();
    this.consoleOutput = consoleOutput;
  }
  @Override public void flush() throws IOException {
    consoleOutput.append(buf.toString("UTF-8"));
    buf.reset();
  }
  @Override public void write(int b) throws IOException {
    buf.write(b);
  }
}
aterai
  • 9,658
  • 4
  • 35
  • 44