001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.widgets; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.Cursor; 007import java.awt.Font; 008import java.awt.event.MouseEvent; 009import java.awt.event.MouseListener; 010 011import javax.swing.Icon; 012import javax.swing.JLabel; 013import javax.swing.SwingUtilities; 014 015import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils; 016import org.openstreetmap.josm.tools.OpenBrowser; 017import org.openstreetmap.josm.tools.Utils; 018 019/** 020 * Label that contains a clickable link. 021 * @since 6340 022 */ 023public class UrlLabel extends JLabel implements MouseListener { 024 025 private String url = ""; 026 private String description = ""; 027 028 /** 029 * Constructs a new empty {@code UrlLabel}. 030 */ 031 public UrlLabel() { 032 init("", "", 0); 033 } 034 035 /** 036 * Constructs a new {@code UrlLabel} for the given URL. 037 * @param url The URL to use, also used as description 038 */ 039 public UrlLabel(String url) { 040 this (url, url, 0); 041 } 042 043 /** 044 * Constructs a new {@code UrlLabel} for the given URL and font increase. 045 * @param url The URL to use, also used as description 046 * @param fontPlus The font increase in 1/72 of an inch units. 047 */ 048 public UrlLabel(String url, int fontPlus) { 049 this (url, url, fontPlus); 050 } 051 052 /** 053 * Constructs a new {@code UrlLabel} for the given URL and description. 054 * @param url The URL to use 055 * @param description The description to display 056 */ 057 public UrlLabel(String url, String description) { 058 this (url, description, 0); 059 } 060 061 /** 062 * Constructs a new {@code UrlLabel} for the given URL, description and image. 063 * @param url The URL to use 064 * @param description The description to display 065 * @param image The image to be displayed by the label instead of text 066 * @since 14822 067 */ 068 public UrlLabel(String url, String description, Icon image) { 069 super(image); 070 init(url, description, 0); 071 } 072 073 /** 074 * Constructs a new {@code UrlLabel} for the given URL, description and font increase. 075 * @param url The URL to use 076 * @param description The description to display 077 * @param fontPlus The font increase in 1/72 of an inch units. 078 */ 079 public UrlLabel(String url, String description, int fontPlus) { 080 init(url, description, fontPlus); 081 } 082 083 private void init(String url, String description, int fontPlus) { 084 addMouseListener(this); 085 setUrl(url); 086 setDescription(description); 087 if (fontPlus != 0) { 088 setFont(getFont().deriveFont(Font.PLAIN, (float) getFont().getSize()+fontPlus)); 089 } 090 refresh(); 091 } 092 093 protected final void refresh() { 094 if (!Utils.isEmpty(url)) { 095 refresh("<html><a color=\"" + JosmEditorPane.getLinkColor() + "\" href=\"" + url + "\">" + description + "</a></html>", 096 Cursor.getPredefinedCursor(Cursor.HAND_CURSOR), 097 String.format("<html>%s<br/>%s</html>", url, tr("Right click = copy to clipboard"))); 098 } else { 099 refresh("<html>" + description + "</html>", null, null); 100 } 101 } 102 103 private void refresh(String text, Cursor cursor, String tooltip) { 104 boolean hasImage = getIcon() != null; 105 if (!hasImage) { 106 setText(text); 107 } 108 setCursor(cursor); 109 setToolTipText(tooltip); 110 } 111 112 /** 113 * Sets the URL to be visited if the user clicks on this URL label. 114 * If null or empty, the label turns into a normal label without hyperlink. 115 * 116 * @param url the url. Can be null. 117 */ 118 public final void setUrl(String url) { 119 this.url = url; 120 refresh(); 121 } 122 123 /** 124 * Sets the text part of the URL label. Defaults to the empty string if description is null. 125 * 126 * @param description the description 127 */ 128 public final void setDescription(String description) { 129 setDescription(description, true); 130 } 131 132 /** 133 * Sets the text part of the URL label. Defaults to the empty string if description is null. 134 * 135 * @param description the description 136 * @param escapeReservedCharacters if {@code true}, HTML reserved characters will be escaped 137 * @since 13853 138 */ 139 public final void setDescription(String description, boolean escapeReservedCharacters) { 140 this.description = description == null ? "" : description; 141 if (escapeReservedCharacters) { 142 this.description = Utils.escapeReservedCharactersHTML(this.description); 143 } 144 refresh(); 145 } 146 147 @Override 148 public void mouseClicked(MouseEvent e) { 149 if (!Utils.isEmpty(url)) { 150 if (SwingUtilities.isLeftMouseButton(e)) { 151 OpenBrowser.displayUrl(url); 152 } else if (SwingUtilities.isRightMouseButton(e)) { 153 ClipboardUtils.copyString(url); 154 } 155 } 156 } 157 158 @Override 159 public void mousePressed(MouseEvent e) { 160 // Ignored 161 } 162 163 @Override 164 public void mouseEntered(MouseEvent e) { 165 // Ignored 166 } 167 168 @Override 169 public void mouseExited(MouseEvent e) { 170 // Ignored 171 } 172 173 @Override 174 public void mouseReleased(MouseEvent e) { 175 // Ignored 176 } 177}