2012-10-03 17 views
5

Estoy tratando de usar JEditorPane para mostrar texto en HTML. Por alguna razón, tengo que usar el método setText(). Sin embargo, eso hace que el JEditorPane parpadee. La razón es que cada vez que se actualiza el editor Panel.setText (msgBuffer); Tengo que llevar el cursor hasta el final del documento editorPane.setCaretPosition ((editorPane.getDocument()). GetLength() - 1) comoIntedo que la línea de texto más reciente aparezca en la parte inferior del documento. Tengo brillante chicos todo el código para que lo veas por ti mismo. He visto muchas recomendaciones sobre el uso de document.insertString, pero para eso tengo que usar atributos individuales que no me interesan. ¿Hay alguna manera de hacer que este código funcione sin parpadeo?Mostrar HTML en JEditorPane usando jEditor.setText() hace que parpadee

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

    } 


} 

Respuesta

5

No debe modificar los componentes de la IU fuera del EDT.

Si agrega una llamada adentro, por ejemplo, su updateMessages para que la actualización ocurra en el EDT, el parpadeo desaparece.

Por ejemplo:

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

Tenga en cuenta que no debe realizar operaciones de larga ejecución en la EDT, porque de lo contrario se va a "bloquear" la interfaz de usuario.

+0

o sin ningún cambio en la interfaz gráfica de usuario visibles – mKorbel

0

Si usted tiene un IO larga duración y una actualización de la interfaz gráfica de usuario después, se puede utilizar en lugar SwingWorker (ver 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(); 
Cuestiones relacionadas