javafx.scene.control.SkinBase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of openjfx-78-backport Show documentation
Show all versions of openjfx-78-backport Show documentation
This is a backport of OpenJFX 8 to run on Java 7.
The newest version!
/*
* Copyright (c) 2012, 2013, 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
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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;
import javafx.css.CssMetaData;
import javafx.css.PseudoClass;
import java.util.Collections;
import java.util.List;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.collections.ObservableList;
import javafx.css.Styleable;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;
/**
*
* @since JavaFX 8.0
*/
public abstract class SkinBase implements Skin {
/***************************************************************************
* *
* Private fields *
* *
**************************************************************************/
/**
* The {@code Control} that is referencing this Skin. There is a
* one-to-one relationship between a {@code Skin} and a {@code Control}.
* When a {@code Skin} is set on a {@code Control}, this variable is
* automatically updated.
*/
private C control;
/**
* A local field that directly refers to the children list inside the Control.
*/
private ObservableList children;
/***************************************************************************
* *
* Event Handlers / Listeners *
* *
**************************************************************************/
/**
* Mouse handler used for consuming all mouse events (preventing them
* from bubbling up to parent)
*/
private static final EventHandler mouseEventConsumer = new EventHandler() {
@Override public void handle(MouseEvent event) {
/*
** we used to consume mouse wheel rotations here,
** be we've switched to ScrollEvents, and only consume those which we use.
** See RT-13995 & RT-14480
*/
event.consume();
}
};
/***************************************************************************
* *
* Constructor *
* *
**************************************************************************/
/**
* Constructor for all SkinBase instances.
*
* @param control The control for which this Skin should attach to.
*/
protected SkinBase(final C control) {
if (control == null) {
throw new IllegalArgumentException("Cannot pass null for control");
}
// Update the control and behavior
this.control = control;
this.children = control.getControlChildren();
// Default behavior for controls is to consume all mouse events
consumeMouseEvents(true);
}
/***************************************************************************
* *
* Public API (from Skin) *
* *
**************************************************************************/
/** {@inheritDoc} */
@Override public final C getSkinnable() {
return control;
}
/** {@inheritDoc} */
@Override public final Node getNode() {
return control;
}
/** {@inheritDoc} */
@Override public void dispose() {
// control.removeEventHandler(ContextMenuEvent.CONTEXT_MENU_REQUESTED, contextMenuHandler);
this.control = null;
}
/***************************************************************************
* *
* Public API *
* *
**************************************************************************/
/**
* Returns the children of the skin.
*/
public final ObservableList getChildren() {
return children;
}
/**
* Called during the layout pass of the scenegraph.
*/
protected void layoutChildren(final double contentX, final double contentY,
final double contentWidth, final double contentHeight) {
// By default simply sizes all managed children to fit within the space provided
for (int i=0, max=children.size(); i Control forwarding API *
* *
**************************************************************************/
/**
* Utility method to get the top inset which includes padding and border
* inset. Then snapped to whole pixels if getSkinnable().isSnapToPixel() is true.
*
* @return Rounded up insets top
*/
protected double snappedTopInset() {
return control.snappedTopInset();
}
/**
* Utility method to get the bottom inset which includes padding and border
* inset. Then snapped to whole pixels if getSkinnable().isSnapToPixel() is true.
*
* @return Rounded up insets bottom
*/
protected double snappedBottomInset() {
return control.snappedBottomInset();
}
/**
* Utility method to get the left inset which includes padding and border
* inset. Then snapped to whole pixels if getSkinnable().isSnapToPixel() is true.
*
* @return Rounded up insets left
*/
protected double snappedLeftInset() {
return control.snappedLeftInset();
}
/**
* Utility method to get the right inset which includes padding and border
* inset. Then snapped to whole pixels if getSkinnable().isSnapToPixel() is true.
*
* @return Rounded up insets right
*/
protected double snappedRightInset() {
return control.snappedRightInset();
}
/**
* If this region's snapToPixel property is true, returns a value rounded
* to the nearest pixel, else returns the same value.
* @param value the space value to be snapped
* @return value rounded to nearest pixel
*/
protected double snapSpace(double value) {
return control.isSnapToPixel() ? Math.round(value) : value;
}
/**
* If this region's snapToPixel property is true, returns a value ceiled
* to the nearest pixel, else returns the same value.
* @param value the size value to be snapped
* @return value ceiled to nearest pixel
*/
protected double snapSize(double value) {
return control.isSnapToPixel() ? Math.ceil(value) : value;
}
/**
* If this region's snapToPixel property is true, returns a value rounded
* to the nearest pixel, else returns the same value.
* @param value the position value to be snapped
* @return value rounded to nearest pixel
*/
protected double snapPosition(double value) {
return control.isSnapToPixel() ? Math.round(value) : value;
}
protected void positionInArea(Node child, double areaX, double areaY,
double areaWidth, double areaHeight, double areaBaselineOffset,
HPos halignment, VPos valignment) {
positionInArea(child, areaX, areaY, areaWidth, areaHeight,
areaBaselineOffset, Insets.EMPTY, halignment, valignment);
}
protected void positionInArea(Node child, double areaX, double areaY,
double areaWidth, double areaHeight, double areaBaselineOffset,
Insets margin, HPos halignment, VPos valignment) {
Region.positionInArea(child, areaX, areaY, areaWidth, areaHeight,
areaBaselineOffset, margin, halignment, valignment,
control.isSnapToPixel());
}
protected void layoutInArea(Node child, double areaX, double areaY,
double areaWidth, double areaHeight,
double areaBaselineOffset,
HPos halignment, VPos valignment) {
layoutInArea(child, areaX, areaY, areaWidth, areaHeight, areaBaselineOffset,
Insets.EMPTY, true, true, halignment, valignment);
}
protected void layoutInArea(Node child, double areaX, double areaY,
double areaWidth, double areaHeight,
double areaBaselineOffset,
Insets margin,
HPos halignment, VPos valignment) {
layoutInArea(child, areaX, areaY, areaWidth, areaHeight, areaBaselineOffset,
margin, true, true, halignment, valignment);
}
protected void layoutInArea(Node child, double areaX, double areaY,
double areaWidth, double areaHeight,
double areaBaselineOffset,
Insets margin, boolean fillWidth, boolean fillHeight,
HPos halignment, VPos valignment) {
Region.layoutInArea(child, areaX, areaY, areaWidth, areaHeight,
areaBaselineOffset, margin, fillWidth, fillHeight, halignment,
valignment, control.isSnapToPixel());
}
/***************************************************************************
* *
* Private Implementation *
* *
**************************************************************************/
/**************************************************************************
* *
* Specialization of CSS handling code *
* *
**************************************************************************/
private static class StyleableProperties {
private static final List> STYLEABLES;
static {
STYLEABLES = Collections.unmodifiableList(Control.getClassCssMetaData());
}
}
/**
* @return The CssMetaData associated with this class, which may include the
* CssMetaData of its super classes.
*/ public static List> getClassCssMetaData() {
return SkinBase.StyleableProperties.STYLEABLES;
}
/**
* This method should delegate to {@link Node#getClassCssMetaData()} so that
* a Node's CssMetaData can be accessed without the need for reflection.
* @return The CssMetaData associated with this node, which may include the
* CssMetaData of its super classes.
*/
public List> getCssMetaData() {
return getClassCssMetaData();
}
/** @see Node#pseudoClassStateChanged */
public final void pseudoClassStateChanged(PseudoClass pseudoClass, boolean active) {
Control ctl = getSkinnable();
if (ctl != null) {
ctl.pseudoClassStateChanged(pseudoClass, active);
}
}
/***************************************************************************
* *
* Testing-only API *
* *
**************************************************************************/
}