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.css.PseudoClass; 29 import javafx.beans.property.ObjectProperty; 30 import javafx.beans.property.ObjectPropertyBase; 31 import javafx.event.ActionEvent; 32 import javafx.event.EventHandler; 33 import javafx.scene.AccessibleAction; 34 import javafx.scene.Node; 35 import javafx.beans.property.ReadOnlyBooleanProperty; 36 import javafx.beans.property.ReadOnlyBooleanWrapper; 37 38 /** 39 * Base class for button-like UI Controls, including Hyperlinks, Buttons, 40 * ToggleButtons, CheckBoxes, and RadioButtons. The primary contribution of 41 * ButtonBase is providing a consistent API for handling the concept of button 42 * "arming". In UIs, a button will typically only "fire" if some user gesture 43 * occurs while the button is "armed". For example, a Button may be armed if 44 * the mouse is pressed and the Button is enabled and the mouse is over the 45 * button. In such a situation, if the mouse is then released, then the Button 46 * is "fired", meaning its action takes place. 47 * @since JavaFX 2.0 48 */ 49 50 public abstract class ButtonBase extends Labeled { 51 52 /*************************************************************************** 53 * * 54 * Constructors * 55 * * 56 **************************************************************************/ 57 58 /** 59 * Create a default ButtonBase with empty text. 60 */ 61 public ButtonBase() { } 62 63 /** 64 * Create a ButtonBase with the given text. 65 * @param text null text is treated as the empty string 66 */ 67 public ButtonBase(String text) { 68 super(text); 69 } 70 71 /** 72 * Create a ButtonBase with the given text and graphic. 73 * @param text null text is treated as the empty string 74 * @param graphic a null graphic is acceptable 75 */ 76 public ButtonBase(String text, Node graphic) { 77 super(text, graphic); 78 } 79 80 81 /*************************************************************************** 82 * * 83 * Properties * 84 * * 85 **************************************************************************/ 86 87 /** 88 * Indicates that the button has been "armed" such that a mouse release 89 * will cause the button's action to be invoked. This is subtly different 90 * from pressed. Pressed indicates that the mouse has been 91 * pressed on a Node and has not yet been released. {@code arm} however 92 * also takes into account whether the mouse is actually over the 93 * button and pressed. 94 */ 95 public final ReadOnlyBooleanProperty armedProperty() { return armed.getReadOnlyProperty(); } 96 private void setArmed(boolean value) { armed.set(value); } 97 public final boolean isArmed() { return armedProperty().get(); } 98 private ReadOnlyBooleanWrapper armed = new ReadOnlyBooleanWrapper() { 99 @Override protected void invalidated() { 100 pseudoClassStateChanged(ARMED_PSEUDOCLASS_STATE, get()); 101 } 102 103 @Override 104 public Object getBean() { 105 return ButtonBase.this; 106 } 107 108 @Override 109 public String getName() { 110 return "armed"; 111 } 112 }; 113 114 /** 115 * The button's action, which is invoked whenever the button is fired. This 116 * may be due to the user clicking on the button with the mouse, or by 117 * a touch event, or by a key press, or if the developer programmatically 118 * invokes the {@link #fire()} method. 119 */ 120 public final ObjectProperty<EventHandler<ActionEvent>> onActionProperty() { return onAction; } 121 public final void setOnAction(EventHandler<ActionEvent> value) { onActionProperty().set(value); } 122 public final EventHandler<ActionEvent> getOnAction() { return onActionProperty().get(); } 123 private ObjectProperty<EventHandler<ActionEvent>> onAction = new ObjectPropertyBase<EventHandler<ActionEvent>>() { 124 @Override protected void invalidated() { 125 setEventHandler(ActionEvent.ACTION, get()); 126 } 127 128 @Override 129 public Object getBean() { 130 return ButtonBase.this; 131 } 132 133 @Override 134 public String getName() { 135 return "onAction"; 136 } 137 }; 138 139 140 /*************************************************************************** 141 * * 142 * Methods * 143 * * 144 **************************************************************************/ 145 146 /** 147 * Arms the button. An armed button will fire an action (whether that be 148 * the action of a {@link Button} or toggling selection on a 149 * {@link CheckBox} or some other behavior) on the next expected UI 150 * gesture. 151 * 152 * @expert This function is intended to be used by experts, primarily 153 * by those implementing new Skins or Behaviors. It is not common 154 * for developers or designers to access this function directly. 155 */ 156 public void arm() { 157 setArmed(true); 158 } 159 160 /** 161 * Disarms the button. See {@link #arm()}. 162 * 163 * @expert This function is intended to be used by experts, primarily 164 * by those implementing new Skins or Behaviors. It is not common 165 * for developers or designers to access this function directly. 166 */ 167 public void disarm() { 168 setArmed(false); 169 } 170 171 /** 172 * Invoked when a user gesture indicates that an event for this 173 * {@code ButtonBase} should occur. 174 * <p> 175 * If invoked, this method will be executed regardless of the status of 176 * {@link #arm}. 177 * </p> 178 */ 179 public abstract void fire(); 180 181 182 /*************************************************************************** 183 * * 184 * Stylesheet Handling * 185 * * 186 **************************************************************************/ 187 188 private static final PseudoClass ARMED_PSEUDOCLASS_STATE = PseudoClass.getPseudoClass("armed"); 189 190 191 /*************************************************************************** 192 * * 193 * Accessibility handling * 194 * * 195 **************************************************************************/ 196 197 @Override 198 public void executeAccessibleAction(AccessibleAction action, Object... parameters) { 199 switch (action) { 200 case FIRE: 201 fire(); 202 break; 203 default: super.executeAccessibleAction(action); 204 } 205 } 206 }