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