JTextPane/JEditorPane和奇怪的文本问题

mai*_*rgs 9 java swing jtextpane jeditorpane

我正在创建一个简单的聊天程序,我想最终显示HTML链接.我现在的问题是我无法将文本显示在我想要的用户名旁边.

我希望用户的名称为粗体,并且文本显示在其旁边,但由于某种原因,非粗体文本显示为居中.

如果我不粗引用户名,它可以正常工作.前两个是我的名字用粗体显示,中间是名称没有粗体,底部显示一个超链接,我希望它看起来像中间两个,但名称加粗.

在此输入图像描述

这是代码,我做错了什么?请注意,我尝试用JEditorPane替换JTextPane,同样的事情发生了.

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

    }

}
Run Code Online (Sandbox Code Playgroud)

sie*_*egi 3

我只是玩了一下并搜索了一下,发现了以下解决方案:

\n\n

设置内容类型后初始化您的JTextPane 内容,如下所示:

\n\n
final String emptyHtml = "<html><body id=\'bodyElement\'></body></html>";\npane.getEditorKit().read(new StringReader(emptyHtml), pane.getDocument(), 0);\n
Run Code Online (Sandbox Code Playgroud)\n\n

之后初始化以下两个新字段(将在方法中使用,只是为了方便):

\n\n
this.doc = (HTMLDocument) pane.getDocument();\nthis.bodyElement = this.doc.getElement("bodyElement");\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在你可以改变你的方法submitALinkWithBold现在你可以像这样

\n\n
final String html =  "<p><b>" + user + ": </b>"\n    + "<a href=\'" + link + "\'>" + link + "</a></p>";\ndoc.insertBeforeEnd(bodyElement, html);\n
Run Code Online (Sandbox Code Playgroud)\n\n

您应该能够将此方案应用于其他两种方法(chatWithBoldchatNoBold)。

\n\n

请注意,在更改所有方法之前,结果看起来不太好(或根本不起作用)。另请注意,即使更改所有方法后,它看起来也不像您原来的示例(更大的行间距,其他字体\xe2\x80\xa6)。我认为这可以通过转换pane.getEditorKit()为 aHTMLEditorKit并使用它来解决setStyleSheet(\xe2\x80\xa6)方法来解决,但我没有尝试这样做。

\n