Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clickable text in a JTextPane

I have a JTextPane declared like the following:

JTextPane box = new JTextPane();
JScrollPane scroll = new JScrollPane();
StyledDocument doc = box.getStyledDocument();
scroll.setViewportView(box);
scroll = new JScrollPane(box);

And I am appending text to it as follows:

public void appendChatText(String text)
{   
    try
    {
        doc.insertString(doc.getLength(), text, null);
        box.setAutoscrolls(true);
        box.setCaretPosition(box.getDocument().getLength());    
    }
    catch(BadLocationException e)
    {
        e.printStackTrace();
    }
}

I also managed to easily get the JTextPane to display images and components as necessary, but I can't figure out how to code clickable text into a JTextPane. For example, I want it to print a message that says something like, "File uploaded to server. Accept *Decline*" and if the user clicks on the accept or decline strings then it executes the appropriate function. Any ideas on how this could be effectively achieved?

like image 824
Joe Avatar asked Apr 21 '13 13:04

Joe


2 Answers

I ended up solving this with a MouseListener and a class extending AsbstractAction. I added the text I wanted to be a clickable link to the JTextPane as follows:

`Style regularBlue = doc.addStyle("regularBlue", StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE));
 StyleConstants.setForeground(regularBlue, Color.BLUE);
 StyleConstants.setUnderline(regularBlue, true);
 regularBlue.addAttribute("linkact", new ChatLinkListener(textLink));
 doc.insertString(doc.getLength(), textLink, regularBlue);`

I initialised the MouseListener on the JTextPane elsewhere and added the following code to my listener class:

public void mouseClicked(MouseEvent e)
        {
            Element ele = doc.getCharacterElement(chatbox.viewToModel(e.getPoint()));
            AttributeSet as = ele.getAttributes();
            ChatLinkListener fla = (ChatLinkListener)as.getAttribute("linkact");
            if(fla != null)
            {
                fla.execute();
            }
        }

And finally, this referenced the class that actually performs the action:

class ChatLinkListener extends AbstractAction
    {
        private String textLink;

        ChatLinkListener(String textLink)
        {
            this.textLink = textLink;
        }

        protected void execute()
        {
            if("accept".equals(url))
            {
                //execute code
            }
            else if("decline".equals(url))
            {
                //execute code
            }
        }

        public void actionPerformed(ActionEvent e)
        {
            execute();
        }
    }
like image 78
Joe Avatar answered Oct 08 '22 17:10

Joe


I also managed to easily get the JTextPane to display images and components as necessary ... I want it to print a message that says something like, "File uploaded to server. Accept Decline"

Why not add buttons for "Accept" and "Decline"?

Otherwise you could use a JEditorPane to display HTML. Then you could add a HyperlinkListener to the "Accept" and "Decline" text. Read the JEditorPane API for an example. The HyperlinkListener expects a URL when you click on the text, but I don't think there is any reason it can't just be a String.

like image 30
camickr Avatar answered Oct 08 '22 15:10

camickr