All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javafx.scene.control.SkinBase Maven / Gradle / Ivy

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                                                        *
     *                                                                         *
     **************************************************************************/      
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy