JavaFX - Вертикальный Аккордеон

Привет у меня есть вопрос, касающийся JavaFX. Я боюсь, что ответ будет скином, о котором я ничего не знаю, но здесь идет.

Я хочу сделать кроссовер Accordion/TabPane в JavaFX. Я попытаюсь объяснить себя в тексте, но далее я включил изображение того, что я пытаюсь сделать.

Итак, я хочу создать контейнер JavaFX с кнопкой слева, чтобы при нажатии на нее перемещался другой связанный контейнер над этим исходным контейнером. При повторном нажатии верхний контейнер переместится обратно влево. Я хочу, чтобы кнопка и верхний контейнер двигались вместе слева направо и обратно, как если бы они были прикреплены друг к другу.

Чтобы было ясно, два разных контейнера предпочтительно должны плавно переходить между ними, как в случае Аккордеона.

1 ответ

Решение

Поместите "стандартный" контент и контент для слайдера (HBox содержащий кнопку и содержимое слайдера) в StackPane и использовать анимацию, чтобы установить translateX таким образом, что ползунок перемещается и выходит из поля зрения:

@Override
public void start(Stage primaryStage) {
    Button someButton = new Button("Sample content");

    StackPane stackPane = new StackPane(someButton);
    stackPane.setPrefSize(500, 500);
    stackPane.setStyle("-fx-background-color: blue;");

    Region sliderContent = new Region();
    sliderContent.setPrefWidth(200);
    sliderContent.setStyle("-fx-background-color: red; -fx-border-color: orange; -fx-border-width: 5;");

    Button expandButton = new Button(">");

    HBox slider = new HBox(sliderContent, expandButton);
    slider.setAlignment(Pos.CENTER);
    slider.setPrefWidth(Region.USE_COMPUTED_SIZE);
    slider.setMaxWidth(Region.USE_PREF_SIZE);

    // start out of view
    slider.setTranslateX(-sliderContent.getPrefWidth());
    StackPane.setAlignment(slider, Pos.CENTER_LEFT);

    // animation for moving the slider
    Timeline timeline = new Timeline(
            new KeyFrame(Duration.ZERO, new KeyValue(slider.translateXProperty(), -sliderContent.getPrefWidth())),
            new KeyFrame(Duration.millis(500), new KeyValue(slider.translateXProperty(), 0d))
    );

    expandButton.setOnAction(evt -> {
        // adjust the direction of play and start playing, if not already done
        String text = expandButton.getText();
        boolean playing = timeline.getStatus() == Animation.Status.RUNNING;
        if (">".equals(text)) {
            timeline.setRate(1);
            if (!playing) {
                timeline.playFromStart();
            }
            expandButton.setText("<");
        } else {
            timeline.setRate(-1);
            if (!playing) {
                timeline.playFrom("end");
            }
            expandButton.setText(">");
        }
    });

    stackPane.getChildren().add(slider);

    final Scene scene = new Scene(stackPane);

    primaryStage.setScene(scene);
    primaryStage.show();
}
Другие вопросы по тегам