[我在“ JavaFX: how to create slide in animation effect for a pane (inside a transparent stage)”上看到了这个问题。而且我不理解John Astralidis发表的最后评论中的部分代码。似乎可以解决我的问题。我想滑动带有阴影舞台的窗格。现在,我的问题是幻灯片动画在视觉根窗格的约束范围之外播放,而只是在舞台(或实际根窗格)的约束下播放。我的视觉根窗格是实际根窗格的子级,我用padding和Corlor.TRANSPARENT设置了实际根窗格,以实现我的可视根窗格阴影效果。对不起,我的英文太烂了,我是一名中国学生。有没有人可以帮助我?谢谢提前给你。
这是我从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();
}
});
}
}
最后,我完成了。我认为John Astralidis的回答是错误的。但是,谢谢。关键是:
希望我的英语水平不好能对别人有所帮助。我将整个演示代码发布在下面:
入门类--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();
}
});
}
}
以及下图: