2012-10-03 29 views
5

Tôi đang cố gắng sử dụng JEditorPane để hiển thị một số văn bản HTML. Đối với một số lý do tôi phải sử dụng phương thức setText(). Tuy nhiên điều đó làm cho JEditorPane nhấp nháy. Lý do là mỗi lần sau khi cập nhật editorPane.setText (msgBuffer); Tôi phải đưa con trỏ đến cuối tài liệu editorPane.setCaretPosition ((editorPane.getDocument()). GetLength() - 1) asI muốn dòng văn bản gần đây nhất xuất hiện ở dưới cùng của tài liệu. Tôi đã sáng cho các bạn toàn bộ mã để bạn tự mình xem nó. Tôi đã thấy nhiều khuyến nghị khi sử dụng document.insertString, nhưng đối với vấn đề đó tôi phải sử dụng các thuộc tính cá nhân mà không phải là sở thích của tôi. Có cách nào để làm cho mã này chạy không bị nhấp nháy không?Hiển thị HTML trong JEditorPane bằng cách sử dụng jEditor.setText() làm cho nó nhấp nháy

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

    } 


} 

Trả lời

5

Bạn không được sửa đổi thành phần giao diện người dùng bên ngoài EDT.

Nếu bạn thêm một cuộc gọi bên trong, hãy nói, cập nhật Messages của bạn để cập nhật diễn ra trên EDT thì nhấp nháy sẽ biến mất.

Ví dụ:

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

Lưu ý rằng bạn không nên thực hiện các thao chạy dài trên EDT vì nếu không bạn sẽ "khóa" giao diện người dùng của bạn.

+0

hoặc không có bất kỳ thay đổi đối với giao diện đồ họa có thể nhìn thấy – mKorbel

0

Nếu bạn có một IO dài chạy và một bản cập nhật để GUI sau đó, bạn có thể sử dụng SwingWorker thay thế (xem 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(); 
Các vấn đề liên quan