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 com.sun.javafx.scene.control.skin; 27 28 import com.sun.javafx.scene.control.behavior.ToggleButtonBehavior; 29 import javafx.scene.control.RadioButton; 30 import javafx.scene.layout.StackPane; 31 32 public class RadioButtonSkin extends LabeledSkinBase<RadioButton, ToggleButtonBehavior<RadioButton>> { 33 34 /** The radio contains the "dot", which is usually a circle */ 35 private StackPane radio; 36 37 /** 38 * Used for laying out the label + radio together as a group 39 * 40 * NOTE: This extra node should be eliminated in the future. 41 * Instead, position inner nodes directly with the utility 42 * functions in Pane (computeXOffset()/computeYOffset()). 43 */ 44 public RadioButtonSkin(RadioButton radioButton) { 45 super(radioButton, new ToggleButtonBehavior<>(radioButton)); 46 47 radio = createRadio(); 48 updateChildren(); 49 } 50 51 @Override protected void updateChildren() { 52 super.updateChildren(); 53 if (radio != null) { 54 getChildren().add(radio); 55 } 56 } 57 58 private static StackPane createRadio() { 59 StackPane radio = new StackPane(); 60 radio.getStyleClass().setAll("radio"); 61 radio.setSnapToPixel(false); 62 StackPane region = new StackPane(); 63 region.getStyleClass().setAll("dot"); 64 radio.getChildren().clear(); 65 radio.getChildren().addAll(region); 66 return radio; 67 } 68 69 70 /*************************************************************************** 71 * * 72 * Layout * 73 * * 74 **************************************************************************/ 75 76 @Override protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) { 77 return super.computeMinWidth(height, topInset, rightInset, bottomInset, leftInset) + snapSize(radio.minWidth(-1)); 78 } 79 80 @Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) { 81 return Math.max(snapSize(super.computeMinHeight(width - radio.minWidth(-1), topInset, rightInset, bottomInset, leftInset)), 82 topInset + radio.minHeight(-1) + bottomInset); 83 } 84 85 @Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) { 86 return super.computePrefWidth(height, topInset, rightInset, bottomInset, leftInset) + snapSize(radio.prefWidth(-1)); 87 } 88 89 @Override protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) { 90 return Math.max(snapSize(super.computePrefHeight(width - radio.prefWidth(-1), topInset, rightInset, bottomInset, leftInset)), 91 topInset + radio.prefHeight(-1) + bottomInset); 92 } 93 94 @Override protected void layoutChildren(final double x, final double y, 95 final double w, final double h) { 96 final RadioButton radioButton = getSkinnable(); 97 final double radioWidth = radio.prefWidth(-1); 98 final double radioHeight = radio.prefHeight(-1); 99 final double computeWidth = Math.max(radioButton.prefWidth(-1),radioButton.minWidth(-1)); 100 final double labelWidth = Math.min(computeWidth - radioWidth, w - snapSize(radioWidth)); 101 final double labelHeight = Math.min(radioButton.prefHeight(labelWidth), h); 102 final double maxHeight = Math.max(radioHeight, labelHeight); 103 final double xOffset = Utils.computeXOffset(w, labelWidth + radioWidth, radioButton.getAlignment().getHpos()) + x; 104 final double yOffset = Utils.computeYOffset(h, maxHeight, radioButton.getAlignment().getVpos()) + y; 105 106 layoutLabelInArea(xOffset + radioWidth, yOffset, labelWidth, maxHeight, radioButton.getAlignment()); 107 radio.resize(snapSize(radioWidth), snapSize(radioHeight)); 108 positionInArea(radio, xOffset, yOffset, radioWidth, maxHeight, 0, radioButton.getAlignment().getHpos(), radioButton.getAlignment().getVpos()); 109 } 110 }