1 /* 2 * Copyright (c) 2010, 2014, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javafx.scene.control; 27 28 import javafx.beans.property.BooleanProperty; 29 import javafx.beans.property.BooleanPropertyBase; 30 import javafx.beans.value.WritableValue; 31 import javafx.event.ActionEvent; 32 import javafx.scene.AccessibleAttribute; 33 import javafx.scene.AccessibleRole; 34 import javafx.scene.Cursor; 35 import javafx.scene.Node; 36 import javafx.css.PseudoClass; 37 38 import com.sun.javafx.scene.control.skin.HyperlinkSkin; 39 40 import javafx.css.StyleableProperty; 41 42 43 /** 44 * <p>An HTML like label which can be a graphic and/or text which responds to rollovers and clicks. 45 * When a hyperlink is clicked/pressed {@link #isVisited} becomes {@code true}. A Hyperlink behaves 46 * just like a {@link Button}. When a hyperlink is pressed and released 47 * a {@link ActionEvent} is sent, and your application can perform some action based on this event. 48 * </p> 49 * 50 * <p>Example:</p> 51 * {@code Hyperlink link = new Hyperlink("www.oracle.com"); } 52 * @since JavaFX 2.0 53 */ 54 public class Hyperlink extends ButtonBase { 55 56 /*************************************************************************** 57 * * 58 * Constructors * 59 * * 60 **************************************************************************/ 61 62 /** 63 * Creates a hyperlink with no label. 64 */ 65 public Hyperlink() { 66 initialize(); 67 } 68 69 /** 70 * Create a hyperlink with the specified text as its label. 71 * 72 * @param text A text string for its label. 73 */ 74 public Hyperlink(String text) { 75 super(text); 76 initialize(); 77 } 78 79 /** 80 * Create a hyperlink with the specified text and graphic as its label. 81 * 82 * @param text A text string for its label. 83 * @param graphic A graphic for its label 84 */ 85 public Hyperlink(String text, Node graphic) { 86 super(text, graphic); 87 initialize(); 88 } 89 90 private void initialize() { 91 // Initialize the style class to be 'hyperlink'. 92 getStyleClass().setAll(DEFAULT_STYLE_CLASS); 93 setAccessibleRole(AccessibleRole.HYPERLINK); 94 // cursor is styleable through css. Calling setCursor 95 // makes it look to css like the user set the value and css will not 96 // override. Initializing cursor by calling applyStyle with null 97 // StyleOrigin ensures that css will be able to override the value. 98 ((StyleableProperty<Cursor>)(WritableValue<Cursor>)cursorProperty()).applyStyle(null, Cursor.HAND); 99 } 100 101 /*************************************************************************** 102 * * 103 * Properties * 104 * * 105 **************************************************************************/ 106 /** 107 * Indicates whether this link has already been "visited". 108 */ 109 public final BooleanProperty visitedProperty() { 110 if (visited == null) { 111 visited = new BooleanPropertyBase() { 112 @Override protected void invalidated() { 113 pseudoClassStateChanged(PSEUDO_CLASS_VISITED, get()); 114 } 115 116 @Override 117 public Object getBean() { 118 return Hyperlink.this; 119 } 120 121 @Override 122 public String getName() { 123 return "visited"; 124 } 125 }; 126 } 127 return visited; 128 } 129 private BooleanProperty visited; 130 public final void setVisited(boolean value) { 131 visitedProperty().set(value); 132 } 133 public final boolean isVisited() { 134 return visited == null ? false : visited.get(); 135 } 136 137 /*************************************************************************** 138 * * 139 * Methods * 140 * * 141 **************************************************************************/ 142 143 /** 144 * Implemented to invoke the {@link ActionEvent} if one is defined. This 145 * function will also {@link #setVisited} to true. 146 */ 147 @Override public void fire() { 148 if (!isDisabled()) { 149 // Avoid causing an exception in the case that visited was bound 150 if (visited == null || !visited.isBound()) { 151 setVisited(true); 152 } 153 fireEvent(new ActionEvent()); 154 } 155 } 156 157 /** {@inheritDoc} */ 158 @Override protected Skin<?> createDefaultSkin() { 159 return new HyperlinkSkin(this); 160 } 161 162 163 /*************************************************************************** 164 * * 165 * Stylesheet Handling * 166 * * 167 **************************************************************************/ 168 169 private static final String DEFAULT_STYLE_CLASS = "hyperlink"; 170 private static final PseudoClass PSEUDO_CLASS_VISITED = 171 PseudoClass.getPseudoClass("visited"); 172 173 /** 174 * Hyperlink uses HAND as the default value for cursor. 175 * This method provides a way for css to get the correct initial value. 176 * @treatAsPrivate implementation detail 177 */ 178 @Deprecated @Override 179 protected /*do not make final*/ Cursor impl_cssGetCursorInitialValue() { 180 return Cursor.HAND; 181 } 182 183 184 /*************************************************************************** 185 * * 186 * Accessibility handling * 187 * * 188 **************************************************************************/ 189 190 @Override 191 public Object queryAccessibleAttribute(AccessibleAttribute attribute, Object... parameters) { 192 switch (attribute) { 193 case VISITED: return isVisited(); 194 default: return super.queryAccessibleAttribute(attribute, parameters); 195 } 196 } 197 }