2012-07-09 25 views
9

Sto creando un semplice programma di chat che voglio alla fine mostrare collegamenti html. Il mio problema adesso è che non riesco a far apparire il testo accanto al nome dell'utente come voglio.JTextPane/JEditorPane e strano problema di testo

Desidero che il nome dell'utente sia in grassetto e il testo venga visualizzato accanto ad esso, ma per qualche motivo il testo non in grassetto appare centrato.

Se non grassetto il nome degli utenti, funziona correttamente. I primi due sono come appare quando ho i nomi in grassetto, la metà è quando il nome non è in grassetto, la parte inferiore mostra un collegamento ipertestuale che voglio che appaia come il secondo, ma con i nomi in grassetto.

enter image description here

Ecco il codice, quello che sto facendo di sbagliato? Si noti che ho provato a sostituire JTextPane con JEditorPane e succede la stessa cosa.

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+ per pubblicare un programma dimostrativo ben funzionante e breve, che mostri bene il problema. –

+1

Non sono un esperto di JTextPane, ma noto che il problema scompare se si commenta 'pane.setContentType (" text/html ");' line. –

+0

Sì, so che il problema va via con quello commentato. Sto usando text/html perché ne ho bisogno per poter visualizzare i collegamenti ipertestuali, e quelli sembrano funzionare solo con set text/html. – systemoutprintln

risposta

3

Ho appena giocato e cercato in giro un po 'e ho trovato la seguente soluzione:

Inizializzare la JTextPanedopo aver impostato il tipo di contenuto con qualcosa di simile:

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

Dopo di che inizializzazione i seguenti due nuovi campi (saranno utilizzati nei metodi, solo per comodità):

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

Ora è possibile cambiare il metodo di submitALinkWithBold in questo modo:

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

si dovrebbe essere in grado di adottare questo schema per gli altri due metodi (chatWithBold e chatNoBold) troppo.

Si noti che il risultato non sembra buono (o non funziona affatto) finché non si cambiano tutti i metodi. Si noti inoltre che, anche dopo aver modificato tutti i metodi, non sembra il vostro esempio originale (interlinea più grande, altro font ...). Penso che questo potrebbe essere risolto gettando pane.getEditorKit() a HTMLEditorKit e usando il suo metodo setStyleSheet(…) ma non l'ho provato.

Problemi correlati