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

com.jfoenix.skins.JFXButtonSkin Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.jfoenix.skins;

import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXButton.ButtonType;
import com.jfoenix.controls.JFXRippler;
import com.jfoenix.effects.JFXDepthManager;
import com.jfoenix.transitions.CachedTransition;
import com.jfoenix.utils.JFXNodeUtils;
import com.sun.javafx.scene.control.skin.ButtonSkin;
import com.sun.javafx.scene.control.skin.LabeledText;
import javafx.animation.*;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.effect.DropShadow;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import javafx.util.Duration;

/**
 * 

Material Design Button Skin

* * @author Shadi Shaheen * @version 1.0 * @since 2016-03-09 */ public class JFXButtonSkin extends ButtonSkin { private Transition clickedAnimation; private JFXRippler buttonRippler; private Runnable releaseManualRippler = null; private boolean invalid = true; private boolean mousePressed = false; public JFXButtonSkin(JFXButton button) { super(button); buttonRippler = new JFXRippler(getSkinnable()) { @Override protected Node getMask() { StackPane mask = new StackPane(); mask.shapeProperty().bind(getSkinnable().shapeProperty()); JFXNodeUtils.updateBackground(getSkinnable().getBackground(), mask); mask.resize(getWidth() - snappedRightInset() - snappedLeftInset(), getHeight() - snappedBottomInset() - snappedTopInset()); return mask; } @Override protected void positionControl(Node control) { // do nothing as the controls is not inside the ripple } }; // add listeners to the button and bind properties button.addEventHandler(MouseEvent.MOUSE_PRESSED, e -> playClickAnimation(1)); // button.addEventHandler(MouseEvent.MOUSE_RELEASED, e -> playClickAnimation(-1)); button.addEventFilter(MouseEvent.MOUSE_PRESSED, e-> mousePressed = true); button.addEventFilter(MouseEvent.MOUSE_RELEASED, e-> mousePressed = false); button.addEventFilter(MouseEvent.MOUSE_DRAGGED, e-> mousePressed = false); button.ripplerFillProperty().addListener((o, oldVal, newVal) -> buttonRippler.setRipplerFill(newVal)); button.armedProperty().addListener((o, oldVal, newVal) -> { if (newVal) { if (!mousePressed) { releaseManualRippler = buttonRippler.createManualRipple(); playClickAnimation(1); } } else { if (releaseManualRippler != null) { releaseManualRippler.run(); releaseManualRippler = null; } playClickAnimation(-1); } }); // show focused state button.focusedProperty().addListener((o, oldVal, newVal) -> { if(!button.disableVisualFocusProperty().get()){ if (newVal){ if (!getSkinnable().isPressed()){ buttonRippler.setOverlayVisible(true); } } else{ buttonRippler.setOverlayVisible(false); } } }); button.buttonTypeProperty().addListener((o, oldVal, newVal) -> updateButtonType(newVal)); /* * disable action when clicking on the button shadow */ button.setPickOnBounds(false); updateButtonType(button.getButtonType()); updateChildren(); } @Override protected void updateChildren() { super.updateChildren(); if(buttonRippler!=null) getChildren().add(0, buttonRippler); for (int i = 1; i < getChildren().size(); i++) { final Node child = getChildren().get(i); if(child instanceof Text) child.setMouseTransparent(true); } } @Override protected void layoutChildren(final double x, final double y, final double w, final double h) { if (invalid) { if (((JFXButton) getSkinnable()).getRipplerFill() == null) { // change rippler fill according to the last LabeledText/Label child for (int i = getChildren().size() - 1; i >= 1; i--) { if (getChildren().get(i) instanceof LabeledText) { buttonRippler.setRipplerFill(((LabeledText) getChildren().get(i)).getFill()); ((LabeledText) getChildren().get(i)).fillProperty() .addListener((o, oldVal, newVal) -> buttonRippler.setRipplerFill( newVal)); break; } else if (getChildren().get(i) instanceof Label) { buttonRippler.setRipplerFill(((Label) getChildren().get(i)).getTextFill()); ((Label) getChildren().get(i)).textFillProperty() .addListener((o, oldVal, newVal) -> buttonRippler.setRipplerFill( newVal)); break; } } } else { buttonRippler.setRipplerFill(((JFXButton) getSkinnable()).getRipplerFill()); } invalid = false; } buttonRippler.resizeRelocate( getSkinnable().getLayoutBounds().getMinX(), getSkinnable().getLayoutBounds().getMinY(), getSkinnable().getWidth(), getSkinnable().getHeight()); layoutLabelInArea(x, y, w, h); } private void updateButtonType(ButtonType type) { switch (type) { case RAISED: JFXDepthManager.setDepth(getSkinnable(), 2); clickedAnimation = new ButtonClickTransition(getSkinnable(), (DropShadow) getSkinnable().getEffect()); break; default: getSkinnable().setEffect(null); break; } } private void playClickAnimation(double rate) { if (clickedAnimation != null) { if(!clickedAnimation.getCurrentTime().equals(clickedAnimation.getCycleDuration()) || rate != 1){ clickedAnimation.setRate(rate); clickedAnimation.play(); } } } private static class ButtonClickTransition extends CachedTransition { ButtonClickTransition(Node node, DropShadow shadowEffect) { super(node, new Timeline( new KeyFrame(Duration.ZERO, new KeyValue(shadowEffect.radiusProperty(), JFXDepthManager.getShadowAt(2).radiusProperty().get(), Interpolator.EASE_BOTH), new KeyValue(shadowEffect.spreadProperty(), JFXDepthManager.getShadowAt(2).spreadProperty().get(), Interpolator.EASE_BOTH), new KeyValue(shadowEffect.offsetXProperty(), JFXDepthManager.getShadowAt(2).offsetXProperty().get(), Interpolator.EASE_BOTH), new KeyValue(shadowEffect.offsetYProperty(), JFXDepthManager.getShadowAt(2).offsetYProperty().get(), Interpolator.EASE_BOTH) ), new KeyFrame(Duration.millis(1000), new KeyValue(shadowEffect.radiusProperty(), JFXDepthManager.getShadowAt(5).radiusProperty().get(), Interpolator.EASE_BOTH), new KeyValue(shadowEffect.spreadProperty(), JFXDepthManager.getShadowAt(5).spreadProperty().get(), Interpolator.EASE_BOTH), new KeyValue(shadowEffect.offsetXProperty(), JFXDepthManager.getShadowAt(5).offsetXProperty().get(), Interpolator.EASE_BOTH), new KeyValue(shadowEffect.offsetYProperty(), JFXDepthManager.getShadowAt(5).offsetYProperty().get(), Interpolator.EASE_BOTH) ) ) ); // reduce the number to increase the shifting , increase number to reduce shifting setCycleDuration(Duration.seconds(0.2)); setDelay(Duration.seconds(0)); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy