JHyperlink.java revision 13978:1993af50385d
1/* 2 * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23package com.sun.swingset3.demos; 24 25import java.awt.Color; 26import java.awt.Cursor; 27import java.awt.Graphics; 28import java.awt.Insets; 29import java.awt.Rectangle; 30import java.awt.event.ActionEvent; 31import java.net.URI; 32import java.net.URISyntaxException; 33import javax.swing.AbstractAction; 34import javax.swing.Action; 35import javax.swing.ButtonModel; 36import javax.swing.Icon; 37import javax.swing.JButton; 38import javax.swing.SwingUtilities; 39import javax.swing.UIManager; 40 41/** 42 * 43 * @author aim 44 */ 45//<snip>Create HTML hyperlink 46//<snip>Create HTML image hyperlink 47public class JHyperlink extends JButton { 48 49 private static final BrowseAction defaultBrowseAction = new BrowseAction(); 50 51 private URI targetURI; 52 private boolean visited; 53 54 private final transient Rectangle viewRect = new Rectangle(); 55 private final transient Rectangle iconRect = new Rectangle(); 56 private final transient Rectangle textRect = new Rectangle(); 57 58 //remind(aim): lookup colors instead of hardcoding them 59 private Color normalForeground; 60 private Color activeForeground; 61 private Color visitedForeground; 62 private boolean drawUnderline = true; 63 64 static { 65 UIManager.put("Hyperlink.foreground", Color.blue); 66 UIManager.put("Hyperlink.activeForeground", Color.red); 67 UIManager.put("Hyperlink.visitedForeground", new Color(85, 145, 90)); 68 } 69 70 /** 71 * Creates a new instance of JHyperlink 72 */ 73 public JHyperlink() { 74 super(); 75 normalForeground = UIManager.getColor("Hyperlink.foreground"); 76 activeForeground = UIManager.getColor("Hyperlink.activeForeground"); 77 visitedForeground = UIManager.getColor("Hyperlink.visitedForeground"); 78 setBorderPainted(false); 79 setContentAreaFilled(false); 80 setForeground(normalForeground); 81 setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); 82 setMargin(new Insets(0, 0, 0, 0)); 83 setAction(defaultBrowseAction); 84 } 85 86 /** 87 * Creates a new instance of JHyperlink 88 */ 89 public JHyperlink(String text) { 90 this(); 91 setText(text); // override the inheritence of the action's name 92 } 93 94 public JHyperlink(String text, String targetURI) throws URISyntaxException { 95 this(text, new URI(targetURI)); 96 } 97 98 public JHyperlink(String text, URI target) { 99 this(text); 100 setTarget(target); 101 } 102 103 public JHyperlink(String text, Action action) { 104 this(text); 105 setAction(action); // replaces default browse action 106 setText(text); // override the inheritence of the action's name 107 } 108 109 public JHyperlink(String text, Icon icon) { 110 this(text); 111 setIcon(icon); 112 } 113 114 public JHyperlink(Icon icon, String targetURI) throws URISyntaxException { 115 this(null, icon, targetURI); 116 } 117 118 public JHyperlink(String text, Icon icon, String targetURI) throws URISyntaxException { 119 this(text, new URI(targetURI)); 120 setIcon(icon); 121 } 122 123 public JHyperlink(String text, Icon icon, URI target) { 124 this(text); 125 setIcon(icon); 126 setTarget(target); 127 } 128 129 public void setTarget(URI target) { 130 this.targetURI = target; 131 setToolTipText(target.toASCIIString()); 132 } 133 134 public URI getTarget() { 135 return targetURI; 136 } 137 138 public void setVisited(boolean visited) { 139 this.visited = visited; 140 } 141 142 public boolean isVisited() { 143 return visited; 144 } 145 146 @Override 147 public void setForeground(Color foreground) { 148 normalForeground = foreground; 149 super.setForeground(foreground); 150 } 151 152 public void setVisitedForeground(Color visited) { 153 visitedForeground = visited; 154 } 155 156 public void setDrawUnderline(boolean drawUnderline) { 157 this.drawUnderline = drawUnderline; 158 } 159 160 public boolean getDrawUnderline() { 161 return drawUnderline; 162 } 163 164 @Override 165 protected void paintComponent(Graphics g) { 166 // Set the foreground on the fly to ensure the text is painted 167 // with the proper color in super.paintComponent 168 ButtonModel model = getModel(); 169 if (model.isArmed()) { 170 super.setForeground(activeForeground); 171 } else if (visited) { 172 super.setForeground(visitedForeground); 173 } else { 174 super.setForeground(normalForeground); 175 } 176 super.paintComponent(g); 177 178 if (drawUnderline) { 179 Insets insets = getInsets(); 180 viewRect.x = insets.left; 181 viewRect.y = insets.top; 182 viewRect.width = getWidth() - insets.left - insets.right; 183 viewRect.height = getHeight() - insets.top - insets.bottom; 184 int baseline = getBaseline(viewRect.width, viewRect.height); 185 186 iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0; 187 textRect.x = textRect.y = textRect.width = textRect.height = 0; 188 SwingUtilities.layoutCompoundLabel(g.getFontMetrics(), getText(), 189 getIcon(), getVerticalAlignment(), getHorizontalAlignment(), 190 getVerticalTextPosition(), getHorizontalTextPosition(), 191 viewRect, iconRect, textRect, getIconTextGap()); 192 193 // getBaseline not returning correct results, so workaround for now 194 if (UIManager.getLookAndFeel().getName().equals("Nimbus")) { 195 baseline += 7; 196 } else { 197 baseline += 3; 198 } 199 200 g.setColor(getForeground()); 201 g.drawLine(textRect.x, 202 baseline, 203 textRect.x + textRect.width, 204 baseline); 205 } 206 207 } 208 209 // This action is stateless and hence can be shared across hyperlinks 210 private static class BrowseAction extends AbstractAction { 211 212 public BrowseAction() { 213 super(); 214 } 215 216 @Override 217 public void actionPerformed(ActionEvent e) { 218 JHyperlink hyperlink = (JHyperlink) e.getSource(); 219 220 URI targetURI = hyperlink.getTarget(); 221 if (targetURI != null) { 222 try { 223 DemoUtilities.browse(targetURI); 224 hyperlink.setVisited(true); 225 } catch (Exception ex) { 226 ex.printStackTrace(); 227 System.err.println(ex); 228 } 229 230 } 231 } 232 233 } 234//</snip> 235//</snip> 236 237} 238