如何为“抽屉”菜单制作自动调整大小的边框窗格

时间:2019-02-02 03:29:40

标签: java animation javafx javafx-8

我以BorderPane作为我的根。左侧包含滑出式菜单,中间包含用于容纳组件的容器。 当滑出菜单隐藏且相反时,我想将主容器的长度拉伸到舞台的宽度。

我试图通过ScaleTransition缩放BorderPane mainContent,但是它出错了。 ScaleTransition只是拉伸,不设置宽度...

enter image description here enter image description here enter image description here

@Override
public void start(Stage primaryStage) throws Exception{
    Label label = new Label("->");
    label.setStyle("-fx-text-fill: orange; -fx-background-color: black");

    VBox content = new VBox();
    content.setStyle("-fx-background-color: purple");

    BorderPane.setAlignment(label, Pos.CENTER);
    BorderPane menu = new BorderPane(content,null,label,null,null);

    menu.setMaxWidth(250);
    menu.setPrefWidth(250);
    menu.setTranslateX(-230);
    menu.setStyle("-fx-background-color: yellow");

    TranslateTransition menuTranslation = new TranslateTransition(Duration.millis(500), menu);
    menuTranslation.setFromX(-230);
    menuTranslation.setToX(0);

    BorderPane mainContent = new BorderPane(new Button("OKEY"),new Button("OKEY"),new Button("OKEY"),new Button("OKEY"),new Button("OKEY"));
    mainContent.setStyle("-fx-background-color: cyan");

    ScaleTransition mainContenTransition = new ScaleTransition(Duration.millis(500), mainContent);
    //TranslateTransition mainContenTranslation = new TranslateTransition(Duration.millis(500), mainContent);

    ParallelTransition parallelTransition = new ParallelTransition();
    parallelTransition.getChildren().addAll(menuTranslation, mainContenTransition);

    menu.setOnMouseEntered(evt -> {
        mainContenTransition.setFromX(mainContent.getWidth());
        mainContenTransition.setToX(primaryStage.getWidth());
        parallelTransition.setRate(1);
        parallelTransition.play();
    });
    menu.setOnMouseExited(evt -> {
        mainContenTransition.setFromX(mainContent.getWidth());
        mainContenTransition.setToX(primaryStage.getWidth());
        parallelTransition.setRate(-1);
        parallelTransition.play();
    });

    mainContent.setStyle("-fx-background-color: cyan");
    BorderPane root = new BorderPane(mainContent, null,null,null, menu);
    primaryStage.setTitle("Hello World");
    primaryStage.setScene(new Scene(root, 800, 600));



    primaryStage.show();
    //mainContent.setScaleX(primaryStage.getWidth());
}

1 个答案:

答案 0 :(得分:3)

所提出的方案使用Timeline来内插所述内容的优选宽度,让布局做的其余部分:

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

public class SideDrawerAnimation extends Application {

    private static final int MENU_CONTENT_WIDTH = 230, MENU_MIN_WIDTH = 20, H = 400, W = 600;
    private static final double SPEED = 2;
    private VBox content;
    private Timeline openMenu, closeMenu;

    @Override
    public void start(Stage primaryStage) throws Exception{

        Label label = new Label("->");
        label.setMinWidth(MENU_MIN_WIDTH);
        label.setPrefWidth(MENU_MIN_WIDTH);
        label.setStyle("-fx-text-fill: orange; -fx-background-color: black");

        content = new VBox();
        content.setPrefWidth(0);
        content.setStyle("-fx-background-color: purple");

        HBox menu = new HBox(content,label);
        menu.setAlignment(Pos.CENTER);
        menu.setMaxWidth(MENU_CONTENT_WIDTH+ MENU_MIN_WIDTH);
        menu.prefWidthProperty().bind(content.prefWidthProperty().add(label.prefWidthProperty()));
        menu.setStyle("-fx-background-color: yellow");

        BorderPane mainContent = new BorderPane(new Label("CENTER"),new Label("TOP"),new Label("RIGHT"),
                new Label("BOTTOM"),new Label("LEFT"));
        mainContent.setStyle("-fx-background-color: cyan");

        openMenu = new Timeline(
                new KeyFrame(Duration.millis(SPEED), event -> setMenuContentPrefSize(openMenu,1))
         );
        openMenu.setCycleCount(Timeline.INDEFINITE);

        closeMenu = new Timeline(
                new KeyFrame(Duration.millis(SPEED), event -> setMenuContentPrefSize(closeMenu, -1))
        );
        closeMenu.setCycleCount(Timeline.INDEFINITE);

        menu.setOnMouseEntered(evt -> {
            closeMenu.stop(); openMenu.play();
        });
        menu.setOnMouseExited(evt -> {
            openMenu.stop(); closeMenu.play();
        });

        HBox root = new HBox(menu, mainContent);
        HBox.setHgrow(mainContent, Priority.ALWAYS);

        Scene scene = new Scene(root, W, H);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void setMenuContentPrefSize(Timeline timeline, int i) {

        double width = content.getPrefWidth();

        if(width > MENU_CONTENT_WIDTH){
            timeline.stop();
            content.setPrefWidth(MENU_CONTENT_WIDTH);

        } else if (width < 0){
            timeline.stop();
            content.setPrefWidth(0);
        } else {
            content.setPrefWidth(width +i);
        }
    }

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

enter image description here