簡體   English   中英

使用jEditor.setText()在JEditorPane中顯示HTML使其閃爍

[英]Displaying HTML in JEditorPane using jEditor.setText() makes it flicker

我正在嘗試使用JEditorPane顯示一些HTML文本。 由於某些原因,我必須使用setText()方法。 但是,這會使JEditorPane閃爍。 原因是每次更新editorPane.setText(msgBuffer);之后, 我必須將光標移到文檔editorPane.setCaretPosition((editorPane.getDocument())。getLength()-1)的末尾,因為我希望最新的文本行出現在文檔底部。 我很高興給大家看完整的代碼,讓您自己看看。 我已經看到了許多有關使用document.insertString的建議,但是出於這個原因,我必須使用與我無關的單個屬性。 有什么辦法可以使此代碼無閃爍運行?

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

    }


}

您不應在EDT外部修改UI組件。

如果在內部添加呼叫,例如updateMessages,以便在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);
            }
        }
    });
}

請注意,您不應在EDT上執行長時間運行的操作,否則將“鎖定” UI。

如果您有長期運行的IO,然后又更新了GUI,則可以改用SwingWorker (請參閱http://en.wikipedia.org/wiki/Event_dispatching_thread

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM