2010-12-14 6 views
9

JPanelを拡張し、JTextPaneを含むクラスがあります(下記参照)。 System.outSystem.errJTextPaneにリダイレクトします。私のクラスは動作していないようです。私はそれを実行すると、システムのプリントをリダイレクトしますが、私のJTextPaneにはプリントしません。助けてください!System.outをJTextPaneにリダイレクト

注:コールは、アプリケーションの起動時にのみリダイレクトされます。しかし、起動後いつでも、System.outコールはJTextPaneにリダイレクトされません。 (すなわち、私がクラスにSystem.out.prinln();を置くと呼び出されますが、後で使用するためにactionListenerに置かれていると、それはリダイレクトされません)。

public class OSXConsole extends JPanel { 
    public static final long serialVersionUID = 21362469L; 

    private JTextPane textPane; 
    private PipedOutputStream pipeOut; 
    private PipedInputStream pipeIn; 


    public OSXConsole() { 
     super(new BorderLayout()); 
     textPane = new JTextPane(); 
     this.add(textPane, BorderLayout.CENTER); 

     redirectSystemStreams(); 

     textPane.setBackground(Color.GRAY); 
     textPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 

    } 


    private void updateTextPane(final String text) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       Document doc = textPane.getDocument(); 
       try { 
        doc.insertString(doc.getLength(), text, null); 
       } catch (BadLocationException e) { 
        throw new RuntimeException(e); 
       } 
       textPane.setCaretPosition(doc.getLength() - 1); 
      } 
     }); 
    } 


    private void redirectSystemStreams() { 
     OutputStream out = new OutputStream() { 
     @Override 
     public void write(final int b) throws IOException { 
      updateTextPane(String.valueOf((char) b)); 
     } 

     @Override 
     public void write(byte[] b, int off, int len) throws IOException { 
      updateTextPane(new String(b, off, len)); 
     } 

     @Override 
     public void write(byte[] b) throws IOException { 
      write(b, 0, b.length); 
     } 
     }; 

     System.setOut(new PrintStream(out, true)); 
     System.setErr(new PrintStream(out, true)); 
    } 


} 
+0

私は間違っていたので私の答えを削除しました。 – jjnguy

+0

一部の通話がリダイレクトされるのを見ていますか? – jjnguy

+0

OSXConsoleクラスからの呼び出しのみがJTextPaneに出力されます。 – Jakir00

答えて

7

パイプによる、常に私を混乱させるストリーム、私のメッセージコンソール・ソリューションは、それらを使用しない理由は次のとおりです。ここで

は、簡単なテストクラスです。とにかくここでは、パイプでストリームを使用してコンソールで私の試みです。相違点のいくつか:

a)JTextAreaがJTextPaneよりも効率的にテキストを表示するだけなので、JTextAreaを使用します。もちろん、テキストに属性を追加する場合は、テキストペインが必要です。

b)このソリューションでは、スレッドを使用します。私は、これが出力のブロックを防ぐために必要であると読んだと確信しています。とにかく私は簡単なテストケースで動作します。

import java.io.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.text.*; 

public class Console implements Runnable 
{ 
    JTextArea displayPane; 
    BufferedReader reader; 

    private Console(JTextArea displayPane, PipedOutputStream pos) 
    { 
     this.displayPane = displayPane; 

     try 
     { 
      PipedInputStream pis = new PipedInputStream(pos); 
      reader = new BufferedReader(new InputStreamReader(pis)); 
     } 
     catch(IOException e) {} 
    } 

    public void run() 
    { 
     String line = null; 

     try 
     { 
      while ((line = reader.readLine()) != null) 
      { 
//    displayPane.replaceSelection(line + "\n"); 
       displayPane.append(line + "\n"); 
       displayPane.setCaretPosition(displayPane.getDocument().getLength()); 
      } 

      System.err.println("im here"); 
     } 
     catch (IOException ioe) 
     { 
      JOptionPane.showMessageDialog(null, 
       "Error redirecting output : "+ioe.getMessage()); 
     } 
    } 

    public static void redirectOutput(JTextArea displayPane) 
    { 
     Console.redirectOut(displayPane); 
     Console.redirectErr(displayPane); 
    } 

    public static void redirectOut(JTextArea displayPane) 
    { 
     PipedOutputStream pos = new PipedOutputStream(); 
     System.setOut(new PrintStream(pos, true)); 

     Console console = new Console(displayPane, pos); 
     new Thread(console).start(); 
    } 

    public static void redirectErr(JTextArea displayPane) 
    { 
     PipedOutputStream pos = new PipedOutputStream(); 
     System.setErr(new PrintStream(pos, true)); 

     Console console = new Console(displayPane, pos); 
     new Thread(console).start(); 
    } 

    public static void main(String[] args) 
    { 
     JTextArea textArea = new JTextArea(); 
     JScrollPane scrollPane = new JScrollPane(textArea); 

     JFrame frame = new JFrame("Redirect Output"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(scrollPane); 
     frame.setSize(200, 100); 
     frame.setVisible(true); 

     Console.redirectOutput(textArea); 
     final int i = 0; 

     Timer timer = new Timer(1000, new ActionListener() 
     { 
      public void actionPerformed(ActionEvent e) 
      { 
       System.out.println(new java.util.Date().toString()); 
       System.err.println(System.currentTimeMillis()); 
      } 
     }); 
     timer.start(); 
    } 
} 
7

Message Console classこれはあなたのためです。

編集:

import java.io.*; 
import java.awt.*; 
import javax.swing.*; 
import javax.swing.event.*; 
import javax.swing.text.*; 

public class MessageConsoleTest 
{ 
    public static int counter; 

    public static void main(String[] args) 
     throws Exception 
    { 
     JTextComponent textComponent = new JTextPane(); 
     JScrollPane scrollPane = new JScrollPane(textComponent); 

     JFrame.setDefaultLookAndFeelDecorated(true); 
     JFrame frame = new JFrame("Message Console"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(scrollPane); 
     frame.setSize(400, 120); 
     frame.setVisible(true); 

     MessageConsole console = new MessageConsole(textComponent); 
     console.redirectOut(); 
     console.redirectErr(Color.RED, null); 

     Timer timer = new Timer(1000, new java.awt.event.ActionListener() 
     { 
      public void actionPerformed(java.awt.event.ActionEvent e) 
      { 
       System.out.println(new java.util.Date().toString()); 
      } 
     }); 
     timer.start(); 

     Thread.sleep(750); 

     Timer timer2 = new Timer(1000, new java.awt.event.ActionListener() 
     { 
      public void actionPerformed(java.awt.event.ActionEvent e) 
      { 
       System.err.println("Error Message: " + ++counter); 
      } 
     }); 
     timer2.start(); 
    } 
} 
+1

私はこれを試しましたが、まったく動作していないようです。 – Jakir00

+0

@Jacob、あなたがシンプルなSSCCE(http://sscce.org)を持っていて、それがうまくいかなかった場合は、ウェブサイトの「お問い合わせ」ページを使って見ることができるコードを送ってください。 – camickr

+0

これを正しく使用すると機能します。ただし、ライブ出力を取得するには、長時間実行されているタスクをSwingWorkerに配置する必要があります。 – CaffeineToCode