modules/controls/src/main/java/javafx/scene/control/skin/ToolBarSkin.java

Print this page
rev 9240 : 8076423: JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization

*** 1,7 **** /* ! * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 2010, 2015 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 21,36 **** * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ ! package com.sun.javafx.scene.control.skin; import java.util.ArrayList; import java.util.Collections; import java.util.List; import com.sun.javafx.scene.traversal.Algorithm; import com.sun.javafx.scene.traversal.ParentTraversalEngine; import com.sun.javafx.scene.traversal.TraversalContext; import javafx.beans.property.ObjectProperty; --- 21,37 ---- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ ! package javafx.scene.control.skin; import java.util.ArrayList; import java.util.Collections; import java.util.List; + import com.sun.javafx.scene.control.behavior.BehaviorBase; import com.sun.javafx.scene.traversal.Algorithm; import com.sun.javafx.scene.traversal.ParentTraversalEngine; import com.sun.javafx.scene.traversal.TraversalContext; import javafx.beans.property.ObjectProperty;
*** 48,57 **** --- 49,59 ---- import javafx.scene.AccessibleAttribute; import javafx.scene.AccessibleRole; import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.control.ContextMenu; + import javafx.scene.control.Control; import javafx.scene.control.MenuItem; import javafx.scene.control.CustomMenuItem; import javafx.scene.control.Separator; import javafx.scene.control.SeparatorMenuItem; import javafx.scene.control.SkinBase;
*** 64,83 **** import javafx.css.StyleableDoubleProperty; import javafx.css.StyleableObjectProperty; import javafx.css.StyleableProperty; import javafx.css.CssMetaData; ! import com.sun.javafx.css.converters.EnumConverter; ! import com.sun.javafx.css.converters.SizeConverter; import com.sun.javafx.scene.control.behavior.ToolBarBehavior; import com.sun.javafx.scene.traversal.Direction; import javafx.css.Styleable; import static com.sun.javafx.scene.control.skin.resources.ControlResources.getString; ! public class ToolBarSkin extends BehaviorSkinBase<ToolBar, ToolBarBehavior> { private Pane box; private ToolBarOverflowMenu overflowMenu; private boolean overflow = false; private double previousWidth = 0; --- 66,97 ---- import javafx.css.StyleableDoubleProperty; import javafx.css.StyleableObjectProperty; import javafx.css.StyleableProperty; import javafx.css.CssMetaData; ! import javafx.css.converter.EnumConverter; ! import javafx.css.converter.SizeConverter; import com.sun.javafx.scene.control.behavior.ToolBarBehavior; import com.sun.javafx.scene.traversal.Direction; import javafx.css.Styleable; import static com.sun.javafx.scene.control.skin.resources.ControlResources.getString; ! /** ! * Default skin implementation for the {@link ToolBar} control. ! * ! * @see ToolBar ! * @since 9 ! */ ! public class ToolBarSkin extends SkinBase<ToolBar> { ! ! /*************************************************************************** ! * * ! * Private fields * ! * * ! **************************************************************************/ private Pane box; private ToolBarOverflowMenu overflowMenu; private boolean overflow = false; private double previousWidth = 0;
*** 85,100 **** private double savedPrefWidth = 0; private double savedPrefHeight = 0; private ObservableList<MenuItem> overflowMenuItems; private boolean needsUpdate = false; private final ParentTraversalEngine engine; - public ToolBarSkin(ToolBar toolbar) { - super(toolbar, new ToolBarBehavior(toolbar)); overflowMenuItems = FXCollections.observableArrayList(); initialize(); ! registerChangeListener(toolbar.orientationProperty(), "ORIENTATION"); engine = new ParentTraversalEngine(getSkinnable(), new Algorithm() { private Node selectPrev(int from, TraversalContext context) { for (int i = from; i >= 0; --i) { --- 99,135 ---- private double savedPrefWidth = 0; private double savedPrefHeight = 0; private ObservableList<MenuItem> overflowMenuItems; private boolean needsUpdate = false; private final ParentTraversalEngine engine; + private final BehaviorBase<ToolBar> behavior; + + + + /*************************************************************************** + * * + * Constructors * + * * + **************************************************************************/ + + /** + * Creates a new ToolBarSkin instance, installing the necessary child + * nodes into the Control {@link Control#getChildren() children} list, as + * well as the necessary input mappings for handling key, mouse, etc events. + * + * @param control The control that this skin should be installed onto. + */ + public ToolBarSkin(ToolBar control) { + super(control); + + // install default input map for the ToolBar control + behavior = new ToolBarBehavior(control); + // control.setInputMap(behavior.getInputMap()); overflowMenuItems = FXCollections.observableArrayList(); initialize(); ! registerChangeListener(control.orientationProperty(), e -> initialize()); engine = new ParentTraversalEngine(getSkinnable(), new Algorithm() { private Node selectPrev(int from, TraversalContext context) { for (int i = from; i >= 0; --i) {
*** 186,196 **** return selectPrev(box.getChildren().size() - 1, context); } }); getSkinnable().setImpl_traversalEngine(engine); ! toolbar.focusedProperty().addListener((observable, oldValue, newValue) -> { if (newValue) { // TODO need to detect the focus direction // to selected the first control in the toolbar when TAB is pressed // or select the last control in the toolbar when SHIFT TAB is pressed. if (!box.getChildren().isEmpty()) { --- 221,231 ---- return selectPrev(box.getChildren().size() - 1, context); } }); getSkinnable().setImpl_traversalEngine(engine); ! control.focusedProperty().addListener((observable, oldValue, newValue) -> { if (newValue) { // TODO need to detect the focus direction // to selected the first control in the toolbar when TAB is pressed // or select the last control in the toolbar when SHIFT TAB is pressed. if (!box.getChildren().isEmpty()) {
*** 199,209 **** overflowMenu.requestFocus(); } } }); ! toolbar.getItems().addListener((ListChangeListener<Node>) c -> { while (c.next()) { for (Node n: c.getRemoved()) { box.getChildren().remove(n); } box.getChildren().addAll(c.getAddedSubList()); --- 234,244 ---- overflowMenu.requestFocus(); } } }); ! control.getItems().addListener((ListChangeListener<Node>) c -> { while (c.next()) { for (Node n: c.getRemoved()) { box.getChildren().remove(n); } box.getChildren().addAll(c.getAddedSubList());
*** 211,230 **** needsUpdate = true; getSkinnable().requestLayout(); }); } private DoubleProperty spacing; ! public final void setSpacing(double value) { spacingProperty().set(snapSpace(value)); } ! public final double getSpacing() { return spacing == null ? 0.0 : snapSpace(spacing.get()); } ! public final DoubleProperty spacingProperty() { if (spacing == null) { spacing = new StyleableDoubleProperty() { @Override protected void invalidated() { --- 246,274 ---- needsUpdate = true; getSkinnable().requestLayout(); }); } + + + /*************************************************************************** + * * + * Properties * + * * + **************************************************************************/ + + // --- spacing private DoubleProperty spacing; ! private final void setSpacing(double value) { spacingProperty().set(snapSpace(value)); } ! private final double getSpacing() { return spacing == null ? 0.0 : snapSpace(spacing.get()); } ! private final DoubleProperty spacingProperty() { if (spacing == null) { spacing = new StyleableDoubleProperty() { @Override protected void invalidated() {
*** 253,272 **** }; } return spacing; } private ObjectProperty<Pos> boxAlignment; ! public final void setBoxAlignment(Pos value) { boxAlignmentProperty().set(value); } ! public final Pos getBoxAlignment() { return boxAlignment == null ? Pos.TOP_LEFT : boxAlignment.get(); } ! public final ObjectProperty<Pos> boxAlignmentProperty() { if (boxAlignment == null) { boxAlignment = new StyleableObjectProperty<Pos>(Pos.TOP_LEFT) { @Override public void invalidated() { --- 297,317 ---- }; } return spacing; } + // --- box alignment private ObjectProperty<Pos> boxAlignment; ! private final void setBoxAlignment(Pos value) { boxAlignmentProperty().set(value); } ! private final Pos getBoxAlignment() { return boxAlignment == null ? Pos.TOP_LEFT : boxAlignment.get(); } ! private final ObjectProperty<Pos> boxAlignmentProperty() { if (boxAlignment == null) { boxAlignment = new StyleableObjectProperty<Pos>(Pos.TOP_LEFT) { @Override public void invalidated() {
*** 295,325 **** }; } return boxAlignment; } ! @Override protected void handleControlPropertyChanged(String property) { ! super.handleControlPropertyChanged(property); ! if ("ORIENTATION".equals(property)) { ! initialize(); } } @Override protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) { final ToolBar toolbar = getSkinnable(); return toolbar.getOrientation() == Orientation.VERTICAL ? computePrefWidth(-1, topInset, rightInset, bottomInset, leftInset) : snapSize(overflowMenu.prefWidth(-1)) + leftInset + rightInset; } @Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) { final ToolBar toolbar = getSkinnable(); return toolbar.getOrientation() == Orientation.VERTICAL? snapSize(overflowMenu.prefHeight(-1)) + topInset + bottomInset : computePrefHeight(-1, topInset, rightInset, bottomInset, leftInset); } @Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) { double prefWidth = 0; final ToolBar toolbar = getSkinnable(); if (toolbar.getOrientation() == Orientation.HORIZONTAL) { --- 340,383 ---- }; } return boxAlignment; } ! ! ! /*************************************************************************** ! * * ! * Public API * ! * * ! **************************************************************************/ ! ! /** {@inheritDoc} */ ! @Override public void dispose() { ! super.dispose(); ! ! if (behavior != null) { ! behavior.dispose(); } } + /** {@inheritDoc} */ @Override protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) { final ToolBar toolbar = getSkinnable(); return toolbar.getOrientation() == Orientation.VERTICAL ? computePrefWidth(-1, topInset, rightInset, bottomInset, leftInset) : snapSize(overflowMenu.prefWidth(-1)) + leftInset + rightInset; } + /** {@inheritDoc} */ @Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) { final ToolBar toolbar = getSkinnable(); return toolbar.getOrientation() == Orientation.VERTICAL? snapSize(overflowMenu.prefHeight(-1)) + topInset + bottomInset : computePrefHeight(-1, topInset, rightInset, bottomInset, leftInset); } + /** {@inheritDoc} */ @Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) { double prefWidth = 0; final ToolBar toolbar = getSkinnable(); if (toolbar.getOrientation() == Orientation.HORIZONTAL) {
*** 338,347 **** --- 396,406 ---- } } return leftInset + prefWidth + rightInset; } + /** {@inheritDoc} */ @Override protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) { double prefHeight = 0; final ToolBar toolbar = getSkinnable(); if(toolbar.getOrientation() == Orientation.VERTICAL) {
*** 360,379 **** --- 419,441 ---- } } return topInset + prefHeight + bottomInset; } + /** {@inheritDoc} */ @Override protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) { return getSkinnable().getOrientation() == Orientation.VERTICAL ? snapSize(getSkinnable().prefWidth(-1)) : Double.MAX_VALUE; } + /** {@inheritDoc} */ @Override protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) { return getSkinnable().getOrientation() == Orientation.VERTICAL ? Double.MAX_VALUE : snapSize(getSkinnable().prefHeight(-1)); } + /** {@inheritDoc} */ @Override protected void layoutChildren(final double x,final double y, final double w, final double h) { // super.layoutChildren(); final ToolBar toolbar = getSkinnable();
*** 453,462 **** --- 515,532 ---- positionInArea(overflowMenu, overflowX, overflowY, overflowMenuWidth, overflowMenuHeight, /*baseline ignored*/0, HPos.CENTER, VPos.CENTER); } } + + + /*************************************************************************** + * * + * Private implementation * + * * + **************************************************************************/ + private void initialize() { if (getSkinnable().getOrientation() == Orientation.VERTICAL) { box = new VBox(); } else { box = new HBox();
*** 594,603 **** --- 664,681 ---- } overflowMenu.setVisible(overflow); overflowMenu.setManaged(overflow); } + + + /*************************************************************************** + * * + * Support classes * + * * + **************************************************************************/ + class ToolBarOverflowMenu extends StackPane { private StackPane downArrow; private ContextMenu popup; private ObservableList<MenuItem> menuItems;
*** 756,766 **** } } /** ! * @return The CssMetaData associated with this class, which may include the * CssMetaData of its super classes. */ public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() { return StyleableProperties.STYLEABLES; } --- 834,844 ---- } } /** ! * Returns the CssMetaData associated with this class, which may include the * CssMetaData of its super classes. */ public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() { return StyleableProperties.STYLEABLES; }