JavaFX:带有阴影效果的舞台时如何正确滑动窗格?[已解决]

问题描述 投票:1回答:1

[我在“ JavaFX: how to create slide in animation effect for a pane (inside a transparent stage)”上看到了这个问题。而且我不理解John Astralidis发表的最后评论中的部分代码。似乎可以解决我的问题。我想滑动带有阴影舞台的窗格。现在,我的问题是幻灯片动画在视觉根窗格的约束范围之外播放,而只是在舞台(或实际根窗格)的约束下播放。我的视觉根窗格是实际根窗格的子级,我用padding和Corlor.TRANSPARENT设置了实际根窗格,以实现我的可视根窗格阴影效果。对不起,我的英文太烂了,我是一名中国学生。有没有人可以帮助我?谢谢提前给你。

slide image

这是我从John Astralidis和Felipe Guizar Diaz修改的代码。起始代码:

@Override
public void start(Stage stage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
    stage.initStyle(StageStyle.TRANSPARENT);
    Scene scene = new Scene(root);//
    stage.setScene(scene);
    stage.show();
}
public static void main(String[] args) {
    launch(args);
}

FXMLDocument.fxml:

<AnchorPane xmlns:fx="http://javafx.com/fxml/1" fx:id="anchorPane" prefWidth="500" prefHeight="500" style="-fx-background-color: transparent;"   
        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>

和控制器FXMLDocumentController.java

public class FXMLDocumentController implements Initializable {
@FXML
private AnchorPane anchorPane;
@FXML
private Button menu;
@FXML
private AnchorPane navList;

private double shadowSize = 15;

@Override
public void initialize(URL url, ResourceBundle rb) {

    Rectangle rectangle = new Rectangle(500,500);

    anchorPane.setClip(rectangle);
    anchorPane.getChildren().add(setupShadowPane());

    prepareSlideMenuAnimation();
}
private Pane setupShadowPane() {
    Pane shadowPane = new Pane();
    shadowPane.setPrefHeight(500);
    shadowPane.setPrefWidth(500);
    shadowPane.setStyle(
            "-fx-background-color: RED;" +
                    "-fx-effect: dropshadow(gaussian, black, " + 20 + ", 0, 0, 0);" +
                    "-fx-background-insets: " + shadowSize + ";"
    );

    Rectangle innerBounds = new Rectangle();
    Rectangle outerBounds = new Rectangle();
    shadowPane.layoutBoundsProperty().addListener((observable, oldBounds, newBounds) -> {
        System.out.println(newBounds.getWidth());
        innerBounds.relocate(newBounds.getMinX() + shadowSize, newBounds.getMinY() + shadowSize);
        innerBounds.setWidth(newBounds.getWidth() - shadowSize * 2);
        innerBounds.setHeight(newBounds.getHeight() - shadowSize * 2);
        outerBounds.setWidth(newBounds.getWidth());
        outerBounds.setHeight(newBounds.getHeight());

        Shape clip = Shape.subtract(outerBounds, innerBounds);
        shadowPane.setClip(clip);
    });

    return shadowPane;
}
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();
        }
    });
}

}

javafx slide shadow stage
1个回答
0
投票

最后,我完成了。我认为John Astralidis的回答是错误的。但是,谢谢。关键是:

  1. 使用StackPane作为实际的根窗格,然后将可视的根窗格和阴影窗格作为StackPane的子级添加到实际的根窗格。视觉的根窗格是需要添加阴影效果窗格的地方。
  2. 设置具有可见外观的芯片的可视根窗格,以显示阴影窗格的阴影效果;
  3. 用带有其内部布局的芯片设置阴影窗格以显示可视根窗格的内容。

希望我的英语水平不好能对别人有所帮助。我将整个演示代码发布在下面:

入门类--FXApplication.java

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class FXApplication extends Application {

@Override
public void start(Stage stage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
    stage.initStyle(StageStyle.TRANSPARENT);
    Scene scene = new Scene(root);//
    scene.setFill(Color.TRANSPARENT);
    stage.setScene(scene);
    stage.show();
}

public static void main(String[] args) {
    launch(args);
}
}

布局FXML文件--FXMLDocument.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<StackPane xmlns:fx="http://javafx.com/fxml/1" fx:id="pane" prefWidth="500" prefHeight="500" style="-fx-background-color: transparent;"
        fx:controller="FXMLDocumentController">
<children>
    <AnchorPane fx:id="anchorPane" prefWidth="500" prefHeight="500" style="-fx-background-color: WHITE;">
        <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>
</children>

控制器类--FXMLDocumentController.java

import javafx.animation.TranslateTransition;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.util.Duration;
import java.net.URL;
import java.util.ResourceBundle;

public class FXMLDocumentController implements Initializable {

@FXML
private AnchorPane anchorPane;
@FXML
private StackPane pane;
@FXML
private Button menu;
@FXML
private AnchorPane navList;
private double shadowSize = 10;

@Override
public void initialize(URL url, ResourceBundle rb) {

    Rectangle rectangle = new Rectangle(480,480);
    rectangle.relocate(10,10);
    anchorPane.setClip(rectangle);
    pane.getChildren().add(setupShadowPane());

    prepareSlideMenuAnimation();
}
private Pane setupShadowPane() {
    Pane shadowPane = new Pane();
    shadowPane.setPrefHeight(500);
    shadowPane.setPrefWidth(500);
    shadowPane.setStyle(
            "-fx-background-color: RED;" +
                    "-fx-effect: dropshadow(gaussian, black, " + 20 + ", 0, 0, 0);" +
                    "-fx-background-insets: " + shadowSize + ";"
    );

    Rectangle innerBounds = new Rectangle();
    Rectangle outerBounds = new Rectangle();
    shadowPane.layoutBoundsProperty().addListener((observable, oldBounds, newBounds) -> {
        innerBounds.relocate(newBounds.getMinX() + shadowSize, newBounds.getMinY() + shadowSize);
        innerBounds.setWidth(newBounds.getWidth() - shadowSize * 2);
        innerBounds.setHeight(newBounds.getHeight() - shadowSize * 2);
        outerBounds.setWidth(newBounds.getWidth());
        outerBounds.setHeight(newBounds.getHeight());

        Shape clip = Shape.subtract(outerBounds, innerBounds);
        shadowPane.setClip(clip);
    });

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

}

以及下图:

enter image description here

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.