1 /* 2 * Copyright (c) 2010, 2015, 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.skin; 27 28 import com.sun.javafx.scene.control.behavior.BehaviorBase; 29 import com.sun.javafx.scene.control.behavior.ToggleButtonBehavior; 30 import com.sun.javafx.scene.control.skin.Utils; 31 import javafx.scene.Node; 32 import javafx.scene.control.Accordion; 33 import javafx.scene.control.Button; 34 import javafx.scene.control.Control; 35 import javafx.scene.control.RadioButton; 36 import javafx.scene.layout.StackPane; 37 38 /** 39 * Default skin implementation for the {@link RadioButton} control. 40 * 41 * @see RadioButton 42 * @since 9 43 */ 44 public class RadioButtonSkin extends LabeledSkinBase<RadioButton> { 45 46 /*************************************************************************** 47 * * 48 * Private fields * 49 * * 50 **************************************************************************/ 51 52 /** The radio contains the "dot", which is usually a circle */ 53 private StackPane radio; 54 private final BehaviorBase<RadioButton> behavior; 55 56 57 58 /*************************************************************************** 59 * * 60 * Constructors * 61 * * 62 **************************************************************************/ 63 64 /** 65 * Creates a new RadioButtonSkin instance, installing the necessary child 66 * nodes into the Control {@link Control#getChildren() children} list, as 67 * well as the necessary input mappings for handling key, mouse, etc events. 68 * 69 * @param control The control that this skin should be installed onto. 70 */ 71 public RadioButtonSkin(RadioButton control) { 72 super(control); 73 74 // install default input map for the RadioButton control 75 behavior = new ToggleButtonBehavior<>(control); 76 // control.setInputMap(behavior.getInputMap()); 77 78 radio = createRadio(); 79 updateChildren(); 80 } 81 82 83 84 /*************************************************************************** 85 * * 86 * Public API * 87 * * 88 **************************************************************************/ 89 90 /** {@inheritDoc} */ 91 @Override public void dispose() { 92 super.dispose(); 93 94 if (behavior != null) { 95 behavior.dispose(); 96 } 97 } 98 99 /** {@inheritDoc} */ 100 @Override protected void updateChildren() { 101 super.updateChildren(); 102 if (radio != null) { 103 getChildren().add(radio); 104 } 105 } 106 107 /** {@inheritDoc} */ 108 @Override protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) { 109 return super.computeMinWidth(height, topInset, rightInset, bottomInset, leftInset) + snapSize(radio.minWidth(-1)); 110 } 111 112 /** {@inheritDoc} */ 113 @Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) { 114 return Math.max(snapSize(super.computeMinHeight(width - radio.minWidth(-1), topInset, rightInset, bottomInset, leftInset)), 115 topInset + radio.minHeight(-1) + bottomInset); 116 } 117 118 /** {@inheritDoc} */ 119 @Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) { 120 return super.computePrefWidth(height, topInset, rightInset, bottomInset, leftInset) + snapSize(radio.prefWidth(-1)); 121 } 122 123 /** {@inheritDoc} */ 124 @Override protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) { 125 return Math.max(snapSize(super.computePrefHeight(width - radio.prefWidth(-1), topInset, rightInset, bottomInset, leftInset)), 126 topInset + radio.prefHeight(-1) + bottomInset); 127 } 128 129 /** {@inheritDoc} */ 130 @Override protected void layoutChildren(final double x, final double y, 131 final double w, final double h) { 132 final RadioButton radioButton = getSkinnable(); 133 final double radioWidth = radio.prefWidth(-1); 134 final double radioHeight = radio.prefHeight(-1); 135 final double computeWidth = Math.max(radioButton.prefWidth(-1),radioButton.minWidth(-1)); 136 final double labelWidth = Math.min(computeWidth - radioWidth, w - snapSize(radioWidth)); 137 final double labelHeight = Math.min(radioButton.prefHeight(labelWidth), h); 138 final double maxHeight = Math.max(radioHeight, labelHeight); 139 final double xOffset = Utils.computeXOffset(w, labelWidth + radioWidth, radioButton.getAlignment().getHpos()) + x; 140 final double yOffset = Utils.computeYOffset(h, maxHeight, radioButton.getAlignment().getVpos()) + y; 141 142 layoutLabelInArea(xOffset + radioWidth, yOffset, labelWidth, maxHeight, radioButton.getAlignment()); 143 radio.resize(snapSize(radioWidth), snapSize(radioHeight)); 144 positionInArea(radio, xOffset, yOffset, radioWidth, maxHeight, 0, radioButton.getAlignment().getHpos(), radioButton.getAlignment().getVpos()); 145 } 146 147 148 149 /*************************************************************************** 150 * * 151 * Private implementation * 152 * * 153 **************************************************************************/ 154 155 private static StackPane createRadio() { 156 StackPane radio = new StackPane(); 157 radio.getStyleClass().setAll("radio"); 158 radio.setSnapToPixel(false); 159 StackPane region = new StackPane(); 160 region.getStyleClass().setAll("dot"); 161 radio.getChildren().clear(); 162 radio.getChildren().addAll(region); 163 return radio; 164 } 165 }