2012-07-09 17 views
9

Estoy creando un programa de chat simple que finalmente quiero mostrar enlaces html. Mi problema ahora es que no puedo hacer que el texto aparezca junto al nombre de los usuarios como yo quiero.JTextPane/JEditorPane y el problema de texto extraño

Quiero que el nombre del usuario sea negrita y que el texto aparezca junto a él, pero por alguna razón el texto no en negrita aparece centrado.

Si no marque el nombre de los usuarios, funciona bien. Los dos primeros son como aparece cuando tengo los nombres en negrita, el medio es cuando el nombre no está en negrita, la parte inferior muestra un hipervínculo, quiero que aparezca como los dos medios, pero con los nombres en negrita.

enter image description here

Aquí está el código, ¿qué estoy haciendo mal? Tenga en cuenta que traté de reemplazar JTextPane con JEditorPane y sucede lo mismo.

package com.test; 

import java.awt.BorderLayout; 
import java.awt.Color; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextPane; 
import javax.swing.WindowConstants; 
import javax.swing.event.HyperlinkEvent; 
import javax.swing.event.HyperlinkEvent.EventType; 
import javax.swing.event.HyperlinkListener; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.SimpleAttributeSet; 
import javax.swing.text.StyleConstants; 
import javax.swing.text.html.HTML; 

public class JTextPaneTest extends JPanel { 

    JTextPane pane; 

    public JTextPaneTest() { 
     this.setLayout(new BorderLayout()); 

     pane = new JTextPane(); 
     pane.setEditable(false); 
     pane.setContentType("text/html"); 

     JScrollPane scrollPane = new JScrollPane(pane); 
     this.add(scrollPane, BorderLayout.CENTER); 

     pane.addHyperlinkListener(new HyperlinkListener() { 

      @Override 
      public void hyperlinkUpdate(HyperlinkEvent e) { 
       if (e.getEventType() == EventType.ACTIVATED) { 
        System.out.println(e.getDescription()); 
       } 

      } 
     }); 

    } 

    public void chatWithBold(String user, String text) { 

     SimpleAttributeSet bold = new SimpleAttributeSet(); 
     StyleConstants.setBold(bold, true); 

     SimpleAttributeSet normal = new SimpleAttributeSet(); 

     try { 
      pane.getDocument().insertString(pane.getDocument().getLength(), 
        user + ": ", bold); 
     } catch (BadLocationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     try { 
      pane.getDocument().insertString(pane.getDocument().getLength(), 
        text + "\n", normal); 
     } catch (BadLocationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    public void chatNoBold(String user, String text) { 

     SimpleAttributeSet bold = new SimpleAttributeSet(); 
     StyleConstants.setBold(bold, true); 

     SimpleAttributeSet normal = new SimpleAttributeSet(); 

     try { 
      pane.getDocument().insertString(pane.getDocument().getLength(), 
        user + ": ", normal); 
     } catch (BadLocationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     try { 
      pane.getDocument().insertString(pane.getDocument().getLength(), 
        text + "\n", normal); 
     } catch (BadLocationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

    private void submitALinkWithBold(String user, String link) { 
     SimpleAttributeSet bold = new SimpleAttributeSet(); 
     StyleConstants.setBold(bold, true); 

     try { 
      pane.getDocument().insertString(pane.getDocument().getLength(), 
        user + ": ", bold); 
     } catch (BadLocationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     SimpleAttributeSet attrs = new SimpleAttributeSet(); 
     attrs.addAttribute(HTML.Attribute.HREF, link); 

     SimpleAttributeSet htmlLink = new SimpleAttributeSet(); 
     htmlLink.addAttribute(HTML.Tag.A, attrs); 
     StyleConstants.setUnderline(htmlLink, true); 
     StyleConstants.setForeground(htmlLink, Color.BLUE); 
     try { 
      pane.getDocument().insertString(pane.getDocument().getLength(), 
        link + "\n", htmlLink); 
     } catch (BadLocationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 

    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 

     JTextPaneTest chat = new JTextPaneTest(); 
     frame.add(chat); 

     frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 

     chat.chatWithBold("User1", "Hi everyone"); 
     chat.chatWithBold("User2", "Hey.. Hows it going"); 

     chat.chatNoBold("User1", "Hi everyone"); 
     chat.chatNoBold("User2", "Hey.. Hows it going"); 

     chat.submitALinkWithBold("User1", "http://www.stackoverflow.com"); 

     frame.setSize(400, 400); 

     frame.setVisible(true); 

    } 

} 
+2

1+ para publicar un programa de demostración breve y que funcione bien, que muestre bien el problema. –

+1

No soy experto en JTextPane, pero observo que el problema desaparece si comenta la línea 'pane.setContentType (" text/html ");'. –

+0

Sí, sé que el problema se va con eso comentado. Estoy usando text/html porque lo necesito para poder mostrar hipervínculos, y esos solo parecen funcionar con el conjunto de texto/html. – systemoutprintln

Respuesta

3

Soy el mejor jugador y busqué un poco y encontré la siguiente solución:

inicializar su JTextPanedespués de establecer el tipo de contenido con algo como esto:

final String emptyHtml = "<html><body id='bodyElement'></body></html>"; 
pane.getEditorKit().read(new StringReader(emptyHtml), pane.getDocument(), 0); 

Después de eso initialize los siguientes dos campos nuevos (se usarán en los métodos, solo por conveniencia):

this.doc = (HTMLDocument) pane.getDocument(); 
this.bodyElement = this.doc.getElement("bodyElement"); 

Ahora puede cambiar su método de submitALinkWithBold así:

final String html = "<p><b>" + user + ": </b>" 
    + "<a href='" + link + "'>" + link + "</a></p>"; 
doc.insertBeforeEnd(bodyElement, html); 

usted debería ser capaz de adoptar este esquema a los otros dos métodos (chatWithBold y chatNoBold) también.

Tenga en cuenta que el resultado no se ve bien (o no funciona en absoluto) hasta que cambie todos sus métodos. También tenga en cuenta que incluso después de cambiar todos los métodos, no se parece a su ejemplo original (espaciado de línea más grande, otra fuente ...). Creo que esto podría solucionarse lanzando pane.getEditorKit() a HTMLEditorKit y usando su método setStyleSheet(…), pero no lo intenté.

Cuestiones relacionadas