gpt4 book ai didi

JavaFX:如何为 Pane 创建幻灯片动画效果(在透明舞台内)

转载 作者:行者123 更新时间:2023-12-04 02:58:34 28 4
gpt4 key购买 nike

我想要一些关于如何在用户按下按钮时为 Pane 实现幻灯片转换的指南,就像 Material Design 为滑动菜单所做的那样。

这是一个视频link这说明了我的需要。

我尝试了 ScaleTransition、TranslateTransition,但他们没有成功。

我试图实现它的方式效率不高。

// swipeMenuPane is builded in SceneBuilder and it is hidden,
// opacity = 0.0 and setX() = -getPrefWidth();
@FXML AnchorPane swipeMenuPane;
@FXML Button menuButton;

menuButton.setOnMouseClicked(e-> {
swipeMenuPane.setOpacity(1.0);
swipeTransition.play()
});

TranslateTransition swipeTransition = new TranslateTransition();
swipeTransition.setNode(swipeMenuPane);
swipeTransition.setDuration(Duration.millis(500));
swipeTransition.setToX(swipeMenuPane.getPrefWidth());

--- 更新 ---

这是从 here 下载的示例 Gluon 应用程序.这是一个 gradle 项目,我对其进行了修改以显示一个按钮而不是默认标签。

当用户单击按钮时,我想缩小 AnchorPane。

我错过了什么?
package com.helloworld;

import com.gluonhq.charm.glisten.animation.ShrinkExpandAnimation;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class HelloWorld extends Application {

ShrinkExpandAnimation anim;

@Override
public void start(Stage stage) {
Button btn = new Button("Click Me!");
btn.setOnMouseClicked(e-> {
System.out.println("swiping...");
anim.play();
});

AnchorPane pane = new AnchorPane();
pane.setStyle("-fx-background-color: coral");
pane.getChildren().add(btn);

// false to shrink or true to expand
anim = new ShrinkExpandAnimation(pane, false);

Scene scene = new Scene(new StackPane(pane), 640, 480);

stage.setScene(scene);
stage.show();
}
}

--- 更新 2 ---

我设法实现了类似于我想要使用 native JavaFX API 并且没有外部库的东西。

虽然,我遇到了一些问题。
  • 收缩 AnchorPane 不会收缩/移动它的任何子节点,因为它们停留在它们的布局位置。
  • 收缩除 AnchorPane 之外的任何其他 Pane 确实会收缩/移动其子节点,但 ImageView 节点除外。

  • 接下来的两张图片说明了我遇到的第一个问题。

    这是 AnchorPane(灰色的根 Pane )内的 AnchorPane(全宽为珊瑚色;展开)。

    expanded

    这就是当您单击菜单按钮以缩小/隐藏它时发生的情况。如您所见,珊瑚色 Pane 已缩小/隐藏,但不是其节点(标签,ImageView)

    collapsed

    我发布了整个代码以自己重现该问题:
    public class SwipeMenuDemo extends Application {

    AnchorPane swapPane;
    Button btnMenu;
    boolean isExpanded = true;

    @Override
    public void start(Stage stage) {
    Label swapPaneLabel = new Label("Expandable Pane");
    swapPaneLabel.setMinWidth(0);

    ImageView swapPaneImage = new ImageView("http://vignette1.wikia.nocookie.net/jfx/images/5/5a/JavaFXIsland600x300.png");
    swapPaneImage.setLayoutY(100);

    Label rootPaneLabel = new Label("Root Pane");
    rootPaneLabel.setStyle("-fx-font-size: 60;");
    rootPaneLabel.setLayoutX(180);
    rootPaneLabel.setLayoutY(180);

    swapPane = new AnchorPane();
    swapPane.setPrefSize(640, 440);
    swapPane.setMinWidth(0);
    swapPane.setLayoutY(40);
    swapPane.setStyle("-fx-background-color: coral; -fx-font-size: 52;");
    swapPane.getChildren().addAll(swapPaneImage, swapPaneLabel);

    btnMenu = new Button("Menu");
    btnMenu.setLayoutX(5);
    btnMenu.setLayoutY(5);
    btnMenu.setOnMouseClicked(e -> {
    if (isExpanded) hideSwapPane().play();
    else showSwapPane().play();
    });

    Button btnClose = new Button("Close");
    btnClose.setLayoutX(590);
    btnClose.setLayoutY(5);
    btnClose.setOnMouseClicked(e -> Platform.exit());

    AnchorPane rootPane = new AnchorPane();
    rootPane.setStyle("-fx-background-color: grey;");
    rootPane.getChildren().addAll(btnMenu, btnClose, rootPaneLabel, swapPane);

    Scene scene = new Scene(rootPane, 640, 480);

    stage.setScene(scene);
    stage.initStyle(StageStyle.UNDECORATED);
    stage.show();
    }

    private Animation hideSwapPane() {
    btnMenu.setMouseTransparent(true);

    Animation collapsePanel = new Transition() {
    {
    setCycleDuration(Duration.millis(2500));
    }

    @Override
    protected void interpolate(double fraction) {
    swapPane.setPrefWidth(640 * (1.0 - fraction));
    }
    };

    collapsePanel.setOnFinished(e-> {
    isExpanded = false;
    btnMenu.setMouseTransparent(false);
    });

    return collapsePanel;
    }

    private Animation showSwapPane() {
    btnMenu.setMouseTransparent(true);

    final Animation expandPanel = new Transition() {
    {
    setCycleDuration(Duration.millis(2500));
    }

    @Override
    protected void interpolate(double fraction) {
    swapPane.setPrefWidth(640 * fraction);
    }
    };

    expandPanel.setOnFinished(e-> {
    isExpanded = true;
    btnMenu.setMouseTransparent(false);
    });

    return expandPanel;
    }
    }

    --- 更新 3 ---

    我根据我的需要修改了 Felipe Guizar Diaz 提供给我的代码,因为我想要在透明舞台窗口上产生阴影效果。

    当我单击菜单按钮以显示左 Pane 时,它显示在阴影前面。即使在 SceneBuilder 中,我已将具有阴影效果的 StackPane 放置在所有节点的前面。

    当我按下显示菜单并开始播放打开的过渡时,这是“神器”......

    我该如何解决?

    shadow artifact

    最佳答案

    我是示例视频的作者。我将重复我在视频评论中所做的回应:
    “您应该将其视为 android 中的抽屉导航,JavaFX 中的抽屉导航将是 AnchorPane 有 2 个 child ,第一个 StackPane 相当于 FrameLayout 作为我们的主要内容,其中的转换 Pane 是根据左侧菜单中选择的项目制作的,最后是 ListView 作为我们的左侧菜单,负数 translateX 等于 Listview 宽度。然后当用户按下按钮时,您必须播放将 translateX 的值设置为 0 的动画。"
    你不应该使用 prefWidth()在两个动画的 interpolate 方法中(折叠面板,展开面板),由于子级不调整大小,边距排列是唯一的约束 AnchorPane拥有。

    看看我做的这个例子。

    https://github.com/marconideveloper/leftsidemenuexample

    public class FXMLDocumentController implements Initializable {

    @FXML
    private Button menu;
    @FXML
    private AnchorPane navList;
    @Override
    public void initialize(URL url, ResourceBundle rb) {
    //navList.setItems(FXCollections.observableArrayList("Red","Yellow","Blue"));
    prepareSlideMenuAnimation();
    }

    private void prepareSlideMenuAnimation() {
    TranslateTransition openNav=new TranslateTransition(new Duration(350), navList);
    openNav.setToX(0);
    TranslateTransition closeNav=new TranslateTransition(new Duration(350), navList);
    menu.setOnAction((ActionEvent evt)->{
    if(navList.getTranslateX()!=0){
    openNav.play();
    }else{
    closeNav.setToX(-(navList.getWidth()));
    closeNav.play();
    }
    });
    }
    }

    这是fxml:
    <AnchorPane xmlns:fx="http://javafx.com/fxml/1" id="AnchorPane" prefWidth="500" prefHeight="500"    fx:controller="leftslidemenusample.FXMLDocumentController">
    <children>

    <ToolBar AnchorPane.topAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" minHeight="56.0" >
    <Button text="menu" fx:id="menu" />
    </ToolBar>
    <StackPane fx:id="mainContent" style="-fx-background-color:rgba(0,0,0,0.30)" AnchorPane.bottomAnchor="0.0" AnchorPane.topAnchor="56.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" >
    <children>

    </children>
    </StackPane>
    <AnchorPane fx:id="navList" style="-fx-background-color:white" AnchorPane.topAnchor="56.0" AnchorPane.bottomAnchor="0.0" prefWidth="180.0" translateX="-180" >
    <children>
    <Label text="left side menu"/>
    </children>
    </AnchorPane>

    </children>

    </AnchorPane>

    关于JavaFX:如何为 Pane 创建幻灯片动画效果(在透明舞台内),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31601900/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com