2013-05-14 79 views
1

在下面的代碼中,我想寫入JEditorPane的數字0到10000.但是,JEditorPane不會顯示任何東西,除非它完全完成(一次打印0到10000)或者os給它時間來刷新和顯示內容。無論是哪種情況,應用程序在一段時間內都沒有響應,而用戶認爲應用程序崩潰了。無論如何,我們可以強制jEditorPane顯示更新的內容,即使它仍然很忙?我嘗試了invokeAndWait,但在這裏沒有幫助,因爲我們不能從事件分派器線程調用invokeAndWait。快速寫入JEditorPane

換句話說,如果我將Thread.sleep(0)替換爲Thread.sleep(50),它可以正常工作,並在結果發生時顯示結果打印,但添加50毫秒的延遲會使其非常緩慢。我所需要的就是不時更新JEditorPane,以便用戶不會認爲應用程序崩潰。 我更喜歡只修改updateMessages()。 這裏是我的代碼:

import javax.swing.JEditorPane; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.SwingUtilities; 
import javax.swing.text.Document; 
import javax.swing.text.html.HTMLEditorKit; 
import javax.swing.text.html.StyleSheet; 

public class CMessageWindowStack { 

    private static final String MESSAGE = "msg"; 
    private JScrollPane scrollPane; 
    public JEditorPane editorPane; 
    private HTMLEditorKit kit; 
    private String msgBuffer=new String(""); 
    private static CMessageWindowStack window=null; 
    private static JFrame frameContainer=null; 

    private CMessageWindowStack() 
    { 
     editorPane = new JEditorPane(); 
     editorPane.setEditable(false); 
     editorPane.setContentType("text/html"); 
     kit = new HTMLEditorKit(); 
     editorPane.setEditorKit(kit); 

     StyleSheet styleSheet = kit.getStyleSheet(); 
     styleSheet.addRule("."+MESSAGE+" {font: 10px monaco; color: black; }"); 

     Document doc = kit.createDefaultDocument(); 
     editorPane.setDocument(doc); 
     scrollPane = new JScrollPane(editorPane); 
    } 
    public static CMessageWindowStack getInstance(){ 
     if (null==window) 
     {window=new CMessageWindowStack();} 
     return window; 
    } 
/** 
* The core 
* @param sMessage 
* @param sType 
*/ 
    private void updateMessages(final String sMessage, final String sType) 

    { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 

     String sMessageHTML=""; 
     String sTypeText=""; 
     if (!sMessage.equals("\r\n")){ 
      sTypeText = sType+": "; 
     } 

     sMessageHTML = sMessage.replaceAll("(\r\n|\n)", "<br/>"); 
     if (!sMessageHTML.equals("<br/>")) 
     { 
      sMessageHTML = "<SPAN CLASS="+sType+">"+ sTypeText+sMessageHTML + "</SPAN>"; 
     } 

     msgBuffer=msgBuffer.concat(sMessageHTML); 
     editorPane.setText(msgBuffer); 
     if ((editorPane.getDocument()).getLength()>1){ 
      editorPane.setCaretPosition((editorPane.getDocument()).getLength()-1); 
     } 
      } 
      }); 
    } 

    public void setContainerFrame(JFrame jFrame){ 
     frameContainer = jFrame; 
     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(frameContainer.getContentPane()); 
     frameContainer.getContentPane().setLayout(layout); 
     layout.setHorizontalGroup(
       layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addComponent(scrollPane) 
       ); 
     layout.setVerticalGroup(
       layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addGroup(layout.createSequentialGroup() 
         .addComponent(scrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 217, Short.MAX_VALUE)) 
       ); 
    } 

    public void setVisible(boolean bVisible){ 
     editorPane.setVisible(bVisible); 
     scrollPane.setVisible(bVisible); 
    } 

    public void printMsg(String sMessage){ 
     String sType = MESSAGE; 
     updateMessages(sMessage,sType); 
    } 

    public void printlnMsg(String sMessage){ 
     sMessage=sMessage.concat("\r\n"); 
     printMsg(sMessage); 
    } 


    public static void main(String args[]){ 
     CMessageWindowStack m_LogMgr; 
     JFrame frame = new JFrame(); 
     m_LogMgr=CMessageWindowStack.getInstance(); 
     m_LogMgr.setContainerFrame(frame); 
     frame.setVisible(true); 
     frame.setSize(500, 500); 


     for(int i=0;i<10000;++i){ 
      try { 
       Thread.sleep(0);//becomes unresponsive if sleep(0) 
      } catch (Exception e) { 
      } 
      m_LogMgr.printlnMsg(i+"-----------------------"); 
     } 

    } 


} 
+0

可能會有一些提示http://java-sl.com/JEditorPanePerformance.html 可以幫助 – StanislavL 2013-05-14 17:25:19

回答

3

你可能會需要使用的SwingWorker。首先加載基本HTML的JEditorPane。那麼你需要publish每行數據。數據發佈後,您需要將文本插入到編輯器窗格中。

基本思想是你不能一次創建一個完整的HTML字符串。

我從來沒有能夠真正理解如何使用動態更改HTML的JEditorPane。也許你可以使用JTextPane。它支持不同的字體和顏色,並且更容易動態更新。

+0

+1。 「SwingWorker」是這裏的正確答案。睡覺幾乎從來都不是正確的答案。 – wchargin 2013-05-14 15:36:10

0

以及 - 作爲一個黑客,你可以嘗試這樣的事:

for(int i=0;i<10000;++i){ 
     try { 
      if(i%100 == 0) { 
       Thread.sleep(10);//becomes unresponsive if sleep(0) 
      } 
     } catch (Exception e) { 
     } 
     m_LogMgr.printlnMsg(i+"-----------------------"); 
    } 
+0

謝謝,但我正在尋找一些解決方案,只需要修改updateMessages。 – 2013-05-14 15:37:57

+0

然後解決方案是一個相當大的努力線程的建議在其他答案..我提供這個黑客,因爲你似乎正在玩睡眠呼叫。 – Randy 2013-05-14 15:39:31

0

您可以嘗試使用線程,並給予它最高的優先級。另外,您可以將-XmX2020選項添加到java.exe。

其他解決方案可能是如果您使用JTextArea而不是JEdiorPane。看起來你用HTML所做的一切就是設計字體。您可以使用JTextArea上的java.awt.Font屬性來執行此操作。