2013-07-13 54 views
1
package htmlconsole; 

import java.awt.BorderLayout; 

public class HTMLConsole extends JFrame { 

    private JPanel contentPane; 
    private JTextPane textPane; 

    public 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); 
     } 

     @Override 
     public void println(String s) 
     { 
      super.println(s); 
      textPane.setText(textPane.getText()+"\n<br>"); 
     }  
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        HTMLConsole frame = new HTMLConsole(); 
        frame.setVisible(true); 

        System.out.println("Hello"); 

       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public HTMLConsole() { 
     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); 

     JTextPane textPane = new JTextPane(); 
     textPane.setEditable(false); 
     textPane.setContentType("text/html"); 
     textPane.setText(""); 

     contentPane.add(textPane, BorderLayout.CENTER); 

     //redirect stream 
     PrintStream interceptor = new Interceptor(System.out); 
     System.setOut(interceptor); 
    } 
} 

輸出:的System.out重定向到的JTextPane

Hellojava.lang.NullPointerException 
    at console.Console$Interceptor.print(Console.java:29) 
    at java.io.PrintStream.println(Unknown Source) 
    at console.Console$Interceptor.println(Console.java:35) 
    at console.Console$1.run(Console.java:47) 
    at java.awt.event.InvocationEvent.dispatch(Unknown Source) 
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
    at java.awt.EventQueue.access$000(Unknown Source) 
    at java.awt.EventQueue$3.run(Unknown Source) 
    at java.awt.EventQueue$3.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
    at java.awt.EventQueue.dispatchEvent(Unknown Source) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
    at java.awt.EventDispatchThread.run(Unknown Source) 

我應該如何糾正這一計劃?這是非常令人困惑的是,這個異常被扔進尚未使用的「打印」方法中!

UPDATE:由textPane = new JTextPane();更換JTextPane textPane = new JTextPane();

異常消失,但現在什麼都沒有顯示在窗口內。 enter image description here

+1

這肯定叫,因爲你調用'System.setOut(攔截);'然後調用'System.out.println(「Hello」);',它自己調用'print()'。 –

+0

請參閱['JTextComponent.read(Reader,Object)'](http://docs.oracle.com/javase/7/docs/api/javax/swing/text/JTextComponent.html#read%28java.io。讀者%20java.lang.Object%29)。另外'setContentType(「text/html」);'沒有任何意義,因爲控制檯的輸出在任何意義上都不是* HTML。 –

+0

@AndrewThompson好的,我已將我的課程更名爲「HTMLConsole」。 – 0x6B6F77616C74

回答

3

你的構造函數調用

JTextPane textPane = new JTextPane(); // local variable declaration and initialization 

而不是調用

this.textPane = new JTextPane() 

所以textPane領域,所使用的攔截器,爲null 。

另請注意,由於堆棧跟蹤顯示,super.println()調用print()。這將導致傳遞給println()的每個字符串被附加到文本窗格兩次。

+1

不錯的觀察+1 – nachokk

2

您在構造函數Console中隱藏變量textPane。更換

JTextPane textPane = new JTextPane(); 

textPane = new JTextPane(); 
3

您可以使用swing的MVC功能實現您的需求。由於JTextPane具有文檔模型,因此您應該考慮將模型適配到流。

public class DocumentPrintStream extends PrintStream { 

    public DocumentPrintStream(Document document, OutputStream delegateStream) { 
     super(delegateStream); 
     this.document = document; 
    } 

    @Override 
    public void print(String string) { 
     int offset = document.getLength(); 
     try { 
      document.insertString(offset, string, null); 
     } catch (BadLocationException e) { 
     } 
     super.print(string); // write to the delegate stream 
    } 
} 

public Console() { 
    ... 
    JTextPane textPane = new JTextPane(); 
    contentPane.add(textPane, BorderLayout.CENTER); 

    // redirect stream 
    Document document = textPane.getDocument(); 
    DocumentPrintStream documentPrintStream = new DocumentPrintStream(
      document, System.out); 
    System.setOut(documentPrintStream); 
} 

它也有,你可以與基於一個Document模型中的每個組件重用DocumentPrintStream的befefit。

例如:

  • 的JEditorPane
  • 的JTextArea
  • 的JTextField
  • 的JTextPane