2012-10-03 9 views
5

一部のHTMLテキストを表示するためにJEditorPaneを使用しようとしています。何らかの理由でsetText()メソッドを使用する必要があります。ただし、これにより、JEditorPaneが点滅します。その理由は、のeditorPane.setText(msgBuffer)を更新した後に毎回更新されるためです。私はドキュメントの末尾にカーソルを持っていなければなりませんeditorPane.setCaretPosition((editorPane.getDocument())。getLength() - 1) as最新のテキスト行をドキュメントの下に表示します。 私はあなた自身のためにそれを見るためにあなたのためのコード全体を明るく持っています。私はdocument.insertStringを使用するための多くの推奨事項を見てきましたが、私の関心がない個々の属性を使用する必要がありました。 このコードをフリッカーフリーにする方法はありますか?jEditor.setText()を使用してJEditorPaneにHTMLを表示するとちらつきが発生します

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

public class CMessageWindow { 

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

    private CMessageWindow() 
    { 
     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; }"); 
     styleSheet.addRule("."+ERROR+" {font: 10px monaco; color: #ff2222; background-color : #cccccc; }"); 

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

    { 
     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 void printErr(String sMessage){ 
     String sType = ERROR; 
     updateMessages(sMessage,sType); 
    } 

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

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

     for(int i=0;i<20;++i){ 
      m_LogMgr.printlnErr("MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM"); 
     } 

     for(int i=0;i<150;++i){ 
      try { 
       Thread.sleep(20); 
      } catch (Exception e) { 
      } 
      m_LogMgr.printlnMsg("-----------------------"); 
     } 

    } 


} 

答えて

5

EDT以外のUIコンポーネントは変更しないでください。

updateMessagesの中にコールを追加して、EDTで更新が行われると、フリッカーが消えます。例えば

:そう、あなたのUIを「ロック」だろうので、あなたがEDT上で長時間実行される操作を実行するべきではありません

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

注意。

+0

または可視GUIを変更せずに(http://en.wikipedia.org/wiki/Event_dispatching_threadを参照)SwingWorkerを使用することができます – mKorbel

0

あなたはその後長く実行しているIOとGUIへの更新を持っている場合は、あなたの代わりに

SwingWorker<Document, Void> worker = new SwingWorker<Document, Void>() { 
    public Document doInBackground() throws IOException { 
     return loadXML(); // heavy task 
    } 

    public void done() { 
     try { 
      Document doc = get(); 
      display(doc); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 
}; 
worker.execute(); 
関連する問題