001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.widgets;
003
004import java.awt.Cursor;
005import java.awt.event.MouseEvent;
006import java.awt.event.MouseListener;
007
008import javax.swing.JLabel;
009import javax.swing.SwingUtilities;
010
011import org.openstreetmap.josm.tools.OpenBrowser;
012import org.openstreetmap.josm.tools.Utils;
013
014import static org.openstreetmap.josm.tools.I18n.tr;
015
016/**
017 * Label that contains a clickable link.
018 * @since 6340
019 */
020public class UrlLabel extends JLabel implements MouseListener {
021
022    private String url = "";
023    private String description = "";
024
025    /**
026     * Constructs a new empty {@code UrlLabel}.
027     */
028    public UrlLabel() {
029        addMouseListener(this);
030        setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
031    }
032
033    /**
034     * Constructs a new {@code UrlLabel} for the given URL.
035     * @param url The URL to use, also used as description
036     */
037    public UrlLabel(String url) {
038        this (url, url, 0);
039    }
040
041    /**
042     * Constructs a new {@code UrlLabel} for the given URL and font increase.
043     * @param url The URL to use, also used as description
044     * @param fontPlus The font increase in 1/72 of an inch units.
045     */
046    public UrlLabel(String url, int fontPlus) {
047        this (url, url, fontPlus);
048    }
049
050    /**
051     * Constructs a new {@code UrlLabel} for the given URL and description.
052     * @param url The URL to use
053     * @param description The description to display 
054     */
055    public UrlLabel(String url, String description) {
056        this (url, description, 0);
057    }
058
059    /**
060     * Constructs a new {@code UrlLabel} for the given URL, description and font increase.
061     * @param url The URL to use
062     * @param description The description to display 
063     * @param fontPlus The font increase in 1/72 of an inch units.
064     */
065    public UrlLabel(String url, String description, int fontPlus) {
066        this();
067        setUrl(url);
068        setDescription(description);
069        if (fontPlus!=0) {
070            setFont(getFont().deriveFont(0, getFont().getSize()+fontPlus));
071        }
072        refresh();
073    }
074
075    protected final void refresh() {
076        if (url != null) {
077            setText("<html><a href=\""+url+"\">"+description+"</a></html>");
078            setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
079            setToolTipText(String.format("<html>%s<br/>%s</html>", url, tr("Right click = copy to clipboard")));
080        } else {
081            setText("<html>" + description + "</html>");
082            setCursor(null);
083            setToolTipText(null);
084        }
085    }
086
087    /**
088     * Sets the URL to be visited if the user clicks on this URL label. If null, the
089     * label turns into a normal label without hyperlink.
090     *
091     * @param url the url. Can be null.
092     */
093    public final void setUrl(String url) {
094        this.url = url;
095        refresh();
096    }
097
098    /**
099     * Sets the text part of the URL label. Defaults to the empty string if description is null.
100     *
101     * @param description the description
102     */
103    public final void setDescription(String description) {
104        this.description = description == null? "" : description;
105        this.description = this.description.replace("&", "&amp;").replace(">", "&gt;").replace("<", "&lt;");
106        refresh();
107    }
108
109    @Override
110    public void mouseClicked(MouseEvent e) {
111        if (SwingUtilities.isLeftMouseButton(e)) {
112            OpenBrowser.displayUrl(url);
113        } else if (SwingUtilities.isRightMouseButton(e)) {
114            Utils.copyToClipboard(url);
115        }
116    }
117    
118    @Override
119    public void mousePressed(MouseEvent e) {
120        // Ignored
121    }
122    
123    @Override
124    public void mouseEntered(MouseEvent e) {
125        // Ignored
126    }
127    
128    @Override
129    public void mouseExited(MouseEvent e) {
130        // Ignored
131    }
132    
133    @Override
134    public void mouseReleased(MouseEvent e) {
135        // Ignored
136    }
137}