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