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;
}