How can I add a clickable url in a JTextPane like this

http://www.google.com

or If I ask other way, how can I make the links in JTextPane clickable ?
When the user click or double click this link the default browser will open the link that is clicked.

I have a JTextPane(EditingArea that extends JTextPane in the code) that is cabable of adding any string with any color with its append function. So I can make the links blue. But I couldn't figure how can I make the links the clickable and open it in the default browser.

I found how can I open the link in the default browser. See my second post below

Note:

I will add the links when program executing. I will make them blue and I know I am adding a URL. So there is no problem that search the text and look for URLs. Maybe this make things simpler for you and me.

import ***
***

public class TextEditor extends JScrollPane {


 public static EditingArea editor;
 final Clipboard clipboard;
 static String copiedSelection = null;

   TextEditor(){
    super();
    editor = new  EditingArea();
    this.setViewportView(editor);
    this.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
    this.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_AS_NEEDED);
    editor.addMouseListener(new MouseClickHandler() );
    clipboard =
          getToolkit().getSystemClipboard();
}

    public class EditingArea extends JTextPane {

  public void append(Color c, String s) { // better implementation--uses
                      // StyleContext
    StyleContext sc = StyleContext.getDefaultStyleContext();
    AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY,
        StyleConstants.Foreground, c);

    int len = getDocument().getLength(); // same value as
                       // getText().length();
    setCaretPosition(len); // place caret at the end (with no selection)
    setCharacterAttributes(aset, false);
    replaceSelection(s); // there is no selection, so inserts at caret
  }
}



}

Edited 5 Years Ago by fenerista: n/a

This code opens the www.nvidia.com in the default browser so opening the link in default browser problem solved. So how can I make the link clickable and get the clicked link ?

import java.net.URI;
import java.awt.Desktop;

public class OpenURI {

    public static void main(String [] args) {

        if( !java.awt.Desktop.isDesktopSupported() ) {

            System.err.println( "Desktop is not supported (fatal)" );
            System.exit( 1 );
        }   

        java.awt.Desktop desktop = java.awt.Desktop.getDesktop();

        if( !desktop.isSupported( java.awt.Desktop.Action.BROWSE ) ) {

            System.err.println( "Desktop doesn't support the browse action (fatal)" );
            System.exit( 1 );
        }

        

            try {

                java.net.URI uri = new java.net.URI( "http://www.nvidia.com" );
                desktop.browse( uri );
            }
            catch ( Exception e ) {

                System.err.println( e.getMessage() );
            }
        
    }
}

Edited 5 Years Ago by fenerista: n/a

1.
when MouseEvent fires mousePressed(MouseEvent e)
then get/append

Transferable trans = clipboard.getContents(null);
            String s1 = (String) trans.getTransferData(DataFlavor.stringFlavor);
            if (s1.equals(s)) {
                //nothing to do (avoid populate text in editor)
                //an alternative to clipboard clear (?)
            } else {
                TextEditor.editor.append(Color.red, s);
                s = s1; // store to compare
            }

where in my case clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();

2.
when CaretEvent fires caretUpdate(CaretEvent e)
then store

text = editor.getSelectedText();

3.
when MouseEvent fires mouseClicked(MouseEvent e)
then deliver

if (e.getClickCount() > 1)
               openURI(text);

1.
when MouseEvent fires mousePressed(MouseEvent e)
then get/append

Transferable trans = clipboard.getContents(null);
            String s1 = (String) trans.getTransferData(DataFlavor.stringFlavor);
            if (s1.equals(s)) {
                //nothing to do (avoid populate text in editor)
                //an alternative to clipboard clear (?)
            } else {
                TextEditor.editor.append(Color.red, s);
                s = s1; // store to compare
            }

where in my case clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();

2.
when CaretEvent fires caretUpdate(CaretEvent e)
then store

text = editor.getSelectedText();

3.
when MouseEvent fires mouseClicked(MouseEvent e)
then deliver

if (e.getClickCount() > 1)
               openURI(text);

in code there is no control for urls maybe you left them to me but I didn't understand. and there is no selectedtext thing. The user will not select the urls the user just click or double click the url that are seen in the editor. You can see the screentshot from my program.(dont pay attention the colors I just wrote them) and clipboard, there is no clipboard action, when the user click the urls.
I am comfused.

Edited 5 Years Ago by fenerista: n/a

Attachments Capture.PNG 5.61 KB

and If you know there is any other class that is capable of adding clickable urls you can offer them to me. there is JEditorPane but jtextpane inherited from this class I think it will not be usefull and I don't know any other editor in java. If you know how adding hyperlink to editor. I can add urls as hyperlinks it is not problem.

Edited 5 Years Ago by fenerista: n/a

Your Document should be a javax.swing.text.html.HTMLDocument
no javax.swing.text.PlainDocument
to force this
editor.setEditable(false);
editor.setPage(url); //url can be local "file://localhost/C:/test.html" (HTML syntax)

This mean, you need use html tags and switch between editable/noneditable modes

Edited 5 Years Ago by quuba: n/a

Attachments url.png 4.13 KB

Your Document should be a javax.swing.text.html.HTMLDocument
no javax.swing.text.PlainDocument
to force this
editor.setEditable(false);
editor.setPage(url); //url can be local "file://localhost/C:/test.html" (HTML syntax)

This mean, you need use html tags and switch between editable/noneditable modes

you say this ? write your text, urls to a html file(let's say it's name is doc.html) and call this code setPage(...doc.html) ?

But it's interesting that :when we use setPage(url), jtextpane can show even a web site url(so it has colorful texts hyperlinks, urls) But it's being hard for me to find how adding a clickable url in a jtextpane:) possibly there is a way to add clickable urls when we are adding them in the code.

and finally I found this post http://www.daniweb.com/forums/post869230.html#post869230 as a reply to "How to Inser Hyperlinks in JTextPane" thread
with SimpleAttributeSet maybe I can do what I want I will try what I found in the web tomorrow and what you have said.

Edited 5 Years Ago by fenerista: n/a

or put url into JEditorPane constructor

public class TextEditor extends JScrollPane {

    public EditingArea editor;

    TextEditor() {
        try {
            editor = new EditingArea("file://localhost/C:/doc.html");
            editor.setEditable(false);
            editor.setDocument((HTMLDocument) editor.getDocument());
        } catch (IOException ex) {
            //
        }
        this.setViewportView(editor);
        this.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
        this.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_AS_NEEDED);
        editor.addHyperlinkListener(new ActivatedHyperlinkListener(editor));

    }
}
public class EditingArea extends JEditorPane {

    EditingArea(String st) throws IOException {
        super(st);
    }
    ...
}

<html>
<head>
<title>test</title>
</head>

<body>
<H3>
<A href="http://www.daniweb.com/" /> http://www.daniweb.com/ </A>

<H3>
<A href="http://www.onet.pl/" /> http://www.onet.pl/ </A>

</body>
</html>

I did without html tags what I want. Maybe it will be useful to somebody.

This text editor has these capabilities:

-adding colorful text to the editor
-adding colorful hyperlink/clickable link to the editor
-when the cursor come over the link it changes to hand cursor.
-if you click the link the program will open the default browser with the clicked link.
-if you select any text on the editor the program will copy it to the clipboard.

import java.net.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
import javax.swing.text.html.*;

public class TextEditor2 extends JScrollPane
{
 public static EditingArea editor;
 final Clipboard clipboard;
 static String copiedSelection = null;

   TextEditor2()
   {
        super();
        editor = new  EditingArea();
        LinkController handler = new LinkController();
        this.setViewportView(editor);
        this.setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
        this.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_AS_NEEDED);
        editor.addMouseListener(handler );
        clipboard = getToolkit().getSystemClipboard();
        editor.addMouseMotionListener( handler );
        //editor.setFont (new Font("Andale Mono", Font.PLAIN, 12));
    }

    public class EditingArea extends JTextPane
    {

      public void append(Color c, String text)
      {
         try{
                Document doc = editor.getDocument();
                SimpleAttributeSet attrs = new SimpleAttributeSet();
                StyleConstants.setForeground(attrs, c);
                doc.insertString(doc.getLength(), text, attrs);
            }
          catch (BadLocationException e)
          {
            e.printStackTrace(System.err);
          }
      }
 
        public void addHyperlink(URL url, String text, Color color)
        {
            try{
                Document doc = editor.getDocument();
                SimpleAttributeSet attrs = new SimpleAttributeSet();
                StyleConstants.setUnderline(attrs, true);
                StyleConstants.setForeground(attrs, color);//unvisited color
                //StyleConstants.setFontSize(null, 13);
                attrs.addAttribute(HTML.Attribute.HREF, url.toString());
                doc.insertString(doc.getLength(), text, attrs);
            }
             catch (BadLocationException e)
             {
                 e.printStackTrace(System.err);
             }
        }
 
    }
    public class LinkController extends MouseAdapter implements MouseMotionListener
    {

           public void mouseReleased(MouseEvent e)
            {
                copiedSelection =editor.getSelectedText();

                if(copiedSelection!=null){
                    StringSelection data = new StringSelection(copiedSelection);
                    clipboard.setContents(data, data);
                }
            }

           public void mouseClicked(MouseEvent e)
          {
              java.awt.Desktop desktop = java.awt.Desktop.getDesktop();
              JTextPane editor = (JTextPane) e.getSource();
              Document doc =  editor.getDocument();
              Point pt = new Point(e.getX(), e.getY());
              int pos = editor.viewToModel(pt);

              if (pos >= 0)
              {
                 if (doc instanceof DefaultStyledDocument){
                      DefaultStyledDocument hdoc = (DefaultStyledDocument) doc;
                      Element el = hdoc.getCharacterElement(pos);
                      AttributeSet a = el.getAttributes();
                      String href = (String) a.getAttribute(HTML.Attribute.HREF);

                      if (href != null){
                        try{
                              java.net.URI uri = new java.net.URI( href );
                              desktop.browse( uri );
                        }
                          catch ( Exception ev ){
                              System.err.println( ev.getMessage() );
                          }
                      }                      
                  }//if (doc instanceof DefaultStyledDocument)
              }// if (pos >= 0)
          }// public void mouseClicked(MouseEvent e)

          public void mouseMoved(MouseEvent ev)
          {

              Cursor handCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
              Cursor defaultCursor = Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR);
              JTextPane editor = (JTextPane) ev.getSource();
              Point pt = new Point(ev.getX(), ev.getY());
              int pos = editor.viewToModel(pt);

              if (pos >= 0){
                Document doc = editor.getDocument();

                if (doc instanceof DefaultStyledDocument){
                  DefaultStyledDocument hdoc = (DefaultStyledDocument) doc;
                  Element e = hdoc.getCharacterElement(pos);
                  AttributeSet a = e.getAttributes();
                  String href = (String) a.getAttribute(HTML.Attribute.HREF);

                  if (href != null){
                      if (getCursor() != handCursor){                         
                        editor.setCursor(handCursor);
                      }
                  }
                  else{        
                        editor.setCursor(defaultCursor);                    
                  }
                }//(doc instanceof DefaultStyledDocument)
              }//pos >=0
              else
              {
                setToolTipText(null);
              }
            }//mouseMoved
        }//LinkController
}//class
This question has already been answered. Start a new discussion instead.