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