JavaFX技巧17:带有AnchorPane的动画工作台布局
最近,我不得不為應用程序實現一個布局,其中可以根據用戶是否登錄來隱藏或通過滑入/滑出動畫顯示或顯示菜單區域和狀態區域。 以下視頻顯示了實際的布局:
在過去,我可能會使用自定義控件和自定義布局代碼來實現這種行為(如“皮膚中的layoutChildren()方法”)。 但是這次我的設置有所不同,因為我使用的是Adam Bien的afterburner.fx ,現在有了FXML和一個控制器類。
那該怎么辦呢? 我決定嘗試使用錨定窗格來實現運氣,并通過時間軸實例更新堆棧窗格上的約束。 約束存儲在堆棧窗格的可觀察屬性映射中。 只要這些限制發生變化,就會自動請求錨定窗格的布局。 如果發生這種情況而沒有任何閃爍,那么我們最終將獲得一個流暢的動畫。 順便說一句,來自Swing,我總是希望閃爍,但是JavaFX通常不會發生閃爍。
最后,我寫了下面的控制器類來管理錨窗格及其子堆棧窗格。 請注意中間屬性menuPaneLocation和bottomPaneLocation的小技巧。 它們是必需的,因為動畫時間軸可與屬性一起使用。 因此,它會更新這些屬性,并且每當它們更改時,都會應用新的錨定窗格約束。
import static javafx.scene.layout.AnchorPane.setBottomAnchor; import static javafx.scene.layout.AnchorPane.setLeftAnchor; import javafx.animation.KeyFrame; import javafx.animation.KeyValue; import javafx.animation.Timeline; import javafx.beans.property.BooleanProperty; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleDoubleProperty; import javafx.fxml.FXML; import javafx.scene.layout.StackPane; import javafx.util.Duration;</code>/*** This presenter covers the top-level layout concepts of the workbench.*/ public class WorkbenchPresenter {@FXML private StackPane topPane;@FXML private StackPane menuPane;@FXML private StackPane centerPane;@FXML private StackPane bottomPane;public WorkbenchPresenter() { }private final BooleanProperty showMenuPane = new SimpleBooleanProperty(this, "showMenuPane", true);public final boolean isShowMenuPane() {return showMenuPane.get(); }public final void setShowMenuPane(boolean showMenu) {showMenuPane.set(showMenu); }/** * Returns the property used to control the visibility of the menu panel. * When the value of this property changes to false then the menu panel will * slide out to the left). * * @return the property used to control the menu panel */ public final BooleanProperty showMenuPaneProperty() {return showMenuPane; }private final BooleanProperty showBottomPane = new SimpleBooleanProperty(this, "showBottomPane", true);public final boolean isShowBottomPane() {return showBottomPane.get(); }public final void setShowBottomPane(boolean showBottom) {showBottomPane.set(showBottom); }/** * Returns the property used to control the visibility of the bottom panel. * When the value of this property changes to false then the bottom panel * will slide out to the left). * * @return the property used to control the bottom panel */ public final BooleanProperty showBottomPaneProperty() {return showBottomPane; }public final void initialize() {menuPaneLocation.addListener(it -> updateMenuPaneAnchors());bottomPaneLocation.addListener(it -> updateBottomPaneAnchors());showMenuPaneProperty().addListener(it -> animateMenuPane());showBottomPaneProperty().addListener(it -> animateBottomPane());menuPane.setOnMouseClicked(evt -> setShowMenuPane(false));centerPane.setOnMouseClicked(evt -> {setShowMenuPane(true);setShowBottomPane(true);});bottomPane.setOnMouseClicked(evt -> setShowBottomPane(false)); }/** The updateMenu/BottomPaneAnchors methods get called whenever the value of* menuPaneLocation or bottomPaneLocation changes. Setting anchor pane* constraints will automatically trigger a relayout of the anchor pane* children.*/private void updateMenuPaneAnchors() {setLeftAnchor(menuPane, getMenuPaneLocation());setLeftAnchor(centerPane, getMenuPaneLocation() + menuPane.getWidth()); }private void updateBottomPaneAnchors() {setBottomAnchor(bottomPane, getBottomPaneLocation());setBottomAnchor(centerPane, getBottomPaneLocation() + bottomPane.getHeight());setBottomAnchor(menuPane,getBottomPaneLocation() + bottomPane.getHeight()); }/* * Starts the animation for the menu pane. */ private void animateMenuPane() {if (isShowMenuPane()) {slideMenuPane(0);} else {slideMenuPane(-menuPane.prefWidth(-1));} }/* * Starts the animation for the bottom pane. */ private void animateBottomPane() {if (isShowBottomPane()) {slideBottomPane(0);} else {slideBottomPane(-bottomPane.prefHeight(-1));} }/** The animations are using the JavaFX timeline concept. The timeline updates* properties. In this case we have to introduce our own properties further* below (menuPaneLocation, bottomPaneLocation) because ultimately we need to* update layout constraints, which are not properties. So this is a little* work-around.*/private void slideMenuPane(double toX) {KeyValue keyValue = new KeyValue(menuPaneLocation, toX);KeyFrame keyFrame = new KeyFrame(Duration.millis(300), keyValue);Timeline timeline = new Timeline(keyFrame);timeline.play(); }private void slideBottomPane(double toY) {KeyValue keyValue = new KeyValue(bottomPaneLocation, toY);KeyFrame keyFrame = new KeyFrame(Duration.millis(300), keyValue);Timeline timeline = new Timeline(keyFrame);timeline.play(); }private DoubleProperty menuPaneLocation = new SimpleDoubleProperty(this, "menuPaneLocation");private double getMenuPaneLocation() {return menuPaneLocation.get(); }private DoubleProperty bottomPaneLocation = new SimpleDoubleProperty(this, "bottomPaneLocation");private double getBottomPaneLocation() {return bottomPaneLocation.get(); } }以下是此項工作所需的FXML:
<?xml version="1.0" encoding="UTF-8"?><?import java.lang.*?> <?import javafx.scene.layout.*?><AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.workbench.WorkbenchPresenter"><children><StackPane fx:id="bottomPane" layoutX="-4.0" layoutY="356.0" prefHeight="40.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" /><StackPane fx:id="menuPane" layoutY="28.0" prefWidth="200.0" AnchorPane.bottomAnchor="40.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="40.0" /><StackPane fx:id="topPane" prefHeight="40.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" /><StackPane fx:id="centerPane" layoutX="72.0" layoutY="44.0" AnchorPane.bottomAnchor="40.0" AnchorPane.leftAnchor="200.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="40.0" /></children> </AnchorPane>翻譯自: https://www.javacodegeeks.com/2015/02/javafx-tip-17-animated-workbench-layout-anchorpane.html
總結
以上是生活随笔為你收集整理的JavaFX技巧17:带有AnchorPane的动画工作台布局的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Java 7或更早版本中使用Java
- 下一篇: 余额宝利率是多少?