TacoB
TacoB

Reputation: 71

How to insert clickable text into a JTextPane?

I've been making a chat program for a few days now and I'm completely stumped on how to create a nice looking clickable text without the use of HTML. I tried to use HTML, but had extremely weird results (see below). So I am now just using basic text rather then text/html.

clickable text with html

My first attempt to add clickable text was to use JTextPane's ability to insert Components along with the text. It inserted and worked perfectly, but it was vertically offset and looked very bad. I tried to mess with setAlignmentY, but had no luck aligning the components with the text.

    JLabel l = new JLabel(test);
    l.setFont(this.getFont());
    l.setCursor(new Cursor(Cursor.HAND_CURSOR));
    l.setBackground(Color.RED); //Just so i could see it better for testing
    l.addMouseListener(new FakeMouseListener());
    this.insertComponent(l);  

I'm using JTextPane and inserting text using doc.insertString. I skip lines using the systems line separator, so a single line can contain multiple doc.insertStrings (Which is were I ran into trouble when attempting to use text/html).

Upvotes: 1

Views: 1707

Answers (2)

user1803551
user1803551

Reputation: 13427

This inserts HTML without any alignment problems. I think ("think" because I don't have enough of your code to know) that you had issues because of Document.insertString while I use HTMLEditorKit.insertHTML.

public class Example extends JFrame {

    Example() {

        JEditorPane pane = new JEditorPane();
        pane.setEditable(false);
        pane.setContentType("text/html");
        HTMLDocument doc = (HTMLDocument) pane.getDocument();
        HTMLEditorKit editorKit = (HTMLEditorKit) pane.getEditorKit();

        try {
            editorKit.insertHTML(doc, doc.getLength(), "<a href=\"http://click.com\">clickable1</a>", 0, 0, null);
            editorKit.insertHTML(doc, doc.getLength(), "<a href=\"c2\">clickable2</a>", 0, 0, null);
            editorKit.insertHTML(doc, doc.getLength(), "<a href=\"c3\">clickable3</a>", 0, 0, null);
        } catch (BadLocationException | IOException e) {
            e.printStackTrace();
        }

        pane.addHyperlinkListener(new HyperlinkListener() {
            
            @Override
            public void hyperlinkUpdate(HyperlinkEvent e) {

                if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
                    System.out.println(e.getSourceElement());
                    if (e.getURL() != null)
                        System.out.println(e.getURL());
                    else
                        System.out.println(e.getDescription());
                    System.out.println("-----");
                }
            }
        });

        add(pane);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String[] args) {

        new Example();
    }
}

Notes:

  • setEditable(false) must be called for this to work properly (probably there is some convoluted way to make it work otherwise).
  • The HyperlinkListener is just to prove that the links work, along with some demonstration of how to get the link string (getURL will only work if the link is a valid URL).
  • You don't need to set the cursor, with or without the HyperlinkListener.

Upvotes: 3

TacoB
TacoB

Reputation: 71

Turns out i put setAlignmentY(0.85f); for the JTextPane instead of the JLable.

If you have an offset component you're attempting to insert into JTextPane, mess around with it's Y alignment. 0.85f works for me.

Upvotes: 0

Related Questions