次の例に示すアプローチでは、他のクラスがインターセプトすると出力ストリームが失われます。プログラムを修正するには?
Console.java:
package interception;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.io.*;
public class Console extends JFrame
{
private JPanel contentPane;
private JTextPane textPane;
private class Interceptor extends PrintStream
{
public Interceptor(OutputStream out)
{
super(out,true);
}
@Override
public void print(String s)
{
super.print(s);
textPane.setText(textPane.getText()+s);
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run()
{
try
{
Console frame = new Console();
frame.setVisible(true);
System.out.print("System standard output stream test\n");
new Troll();
System.out.print("Haters gonna hate\n");
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Console()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
textPane = new JTextPane();
textPane.setEditable(false);
contentPane.add(textPane, BorderLayout.CENTER);
redirectStream();
}
protected void redirectStream()
{
PrintStream iout = new Interceptor(System.out);
System.setOut(iout);
}
}
トロール.java:
package interception;
import java.io.*;
public class Troll
{
private class Interceptor extends PrintStream
{
public Interceptor(OutputStream out)
{
super(out,true);
}
@Override
public void print(String s)
{
super.print(s);
}
}
public Troll()
{
PrintStream iout = new Interceptor(System.out);
System.setOut(iout);
System.out.print("I've stolen your stream bwahaha!\n");
}
}
つまり、「トロール」の構築後、コンソールは出力ストリームをインターセプトできなくなるため、「ヘイターズ ゴング ヘイト」というテキストは内部に表示されません。これが問題です。
アップデート
クラスのストリームを閉じることTroll
は、明らかに受け入れられない解決策です。