2012-07-09 33 views
9

Tôi đang tạo một chương trình trò chuyện đơn giản mà tôi muốn hiển thị liên kết html cuối cùng. Vấn đề của tôi bây giờ là tôi không thể hiển thị văn bản bên cạnh tên người dùng như tôi muốn.JTextPane/JEditorPane và vấn đề văn bản lạ

Tôi muốn tên của người dùng được in đậm và văn bản xuất hiện ngay bên cạnh nó, nhưng vì lý do nào đó, văn bản không in đậm sẽ xuất hiện ở giữa.

Nếu tôi không in đậm tên người dùng, nó hoạt động tốt. Đầu hai là làm thế nào nó xuất hiện khi tôi có tên in đậm, giữa là khi tên không được in đậm, phía dưới cho thấy một siêu liên kết tôi muốn nó xuất hiện như giữa hai, nhưng với tên in đậm.

enter image description here

Đây là mã, tôi đang làm gì sai? Lưu ý rằng tôi đã thử thay thế JTextPane bằng JEditorPane và điều tương tự cũng xảy ra.

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+ để đăng một chương trình demo ngắn và hoạt động tốt, một chương trình hiển thị sự cố tốt. –

+1

Tôi không có chuyên gia JTextPane, nhưng tôi lưu ý rằng sự cố sẽ biến mất nếu bạn nhận xét ra dòng 'pane.setContentType (" text/html ");' line. –

+0

Vâng, tôi biết vấn đề sẽ biến mất khi nhận xét. Tôi đang sử dụng text/html bởi vì tôi cần nó để có thể hiển thị các siêu liên kết, và những người dường như chỉ làm việc với văn bản/tập html. – systemoutprintln

Trả lời

3

Tôi chỉ chơi và đã tìm kiếm xung quanh một chút và tìm thấy các giải pháp sau đây:

Khởi bạn JTextPanesau khi thiết lập các kiểu nội dung với một cái gì đó như thế này:

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

Sau khi khởi tạo mà hai trường mới sau (sẽ được sử dụng trong các phương thức, chỉ để thuận tiện):

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

Bây giờ bạn có thể thay đổi phương pháp của bạn submitALinkWithBold như thế này:

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

Bạn sẽ có thể áp dụng chương trình này để hai phương pháp khác (chatWithBoldchatNoBold) quá.

Lưu ý rằng kết quả không tốt (hoặc không hoạt động chút nào) cho đến khi bạn thay đổi tất cả các phương pháp của mình. Cũng lưu ý rằng ngay cả sau khi thay đổi tất cả các phương pháp, nó không giống như ví dụ ban đầu của bạn (khoảng cách dòng lớn hơn, phông chữ khác…). Tôi nghĩ rằng điều này có thể được khắc phục bằng cách truyền pane.getEditorKit() đến một số HTMLEditorKit và sử dụng phương thức setStyleSheet(…) nhưng tôi không thử.

Các vấn đề liên quan