【问题标题】:JavaFX:How to slide a pane properly when stage with shadow effect?JavaFX:如何在具有阴影效果的舞台上正确滑动窗格?
【发布时间】:2019-12-28 12:30:32
【问题描述】:

我在“JavaFX: how to create slide in animation effect for a pane (inside a transparent stage)”上看到了这个问题。

我不明白 John Astralidis 发表的最后一条评论的部分代码。它似乎解决了我的问题。我想滑动带有阴影舞台的窗格。现在我的问题是幻灯片动画播放超出了我的可视根窗格绑定,它只是在舞台(或实际根窗格)绑定中播放。

我的视觉根窗格是实际根窗格的子窗格,我使用填充和 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();
        }
    });
}

}

【问题讨论】:

  • 有谁能帮帮我吗?阴影效果有错吗?我的阴影效果是由两个窗格创建的,可视根窗格和实际根窗格,可视根窗格是实际窗格的子窗格。我设置带有填充和舞台初始化样式和场景'填充透明的实际根窗格,然后使用“-fx-effect”设置视觉根窗格阴影效果。如何在视觉根窗格而不是实际根窗格上滑动窗格?

标签: javafx slide shadow stage


【解决方案1】:

最后,我完成了。我认为 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();
        }
    });
}

}

还有下图:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-21
    • 1970-01-01
    • 2015-10-14
    • 1970-01-01
    • 2012-11-02
    • 2019-08-05
    • 1970-01-01
    • 2012-10-18
    相关资源
    最近更新 更多