Clickable text in a JTextPane
Asked Answered
L

5

8

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?

Lumberman answered 21/4, 2013 at 13:47 Comment(0)
L
7

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();
        }
    }
Lumberman answered 23/4, 2013 at 16:24 Comment(0)
R
3

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.

Rafaelrafaela answered 21/4, 2013 at 17:39 Comment(1)
Thanks, I'll try this out when I have the time in a few days. If the issue is solved I'll accept the answer. Personality trying to avoid using buttons to keep it looking neat and clean, so a HyperLinkListener sounds like the road I'll be taking. :)Lumberman
B
3

If you dont like to use buttons, then use a JLabel.

If you are using a JTextPane you can use the insertComponent() method to insert a new JLabel that is of the same font as the JTextPane font and you can customize the JLabel the way you want like setting the cursor to hand cursor thereby giving it a clickable look and feel.

JLabel l=new JLabel("Click me");
l.setFont(textPane.getFont());
l.setCursor(new Cursor(Cursor.HAND_CURSOR));
l.addMouseListener(new MouseAdapter(){
   public void mouseClicked(MouseEvent me)
   {
         // your code
   }
});
textPane.insertComponent(l);
Box answered 8/7, 2013 at 18:45 Comment(0)
T
2

Add mouselistener to the text you want clickable and perform appropriate action.

Tenatenable answered 21/4, 2013 at 14:1 Comment(0)
D
0

I think its the "JOptionPane" class that you want It should give you option buttons to choose from - eg:("ok"/"cancel")

Degust answered 21/4, 2013 at 15:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.