Ivar Eriksson
Ivar Eriksson

Reputation: 973

JavaFX - Vertical Accordion

Hi I have a question concerning JavaFX. I fear the answer to be skinning which I know nothing about but here goes.

I want to make an Accordion/TabPane crossover in JavaFX. I will try to explain myself in text but further down I have included an image of what I am trying to make.

So, I want to make a JavaFX container with a button to the left that when clicked will move a different related container over this initial container. When pressed again the top container will move back to the left. I want the button and the top container to move together from the left to the right and back again as if they were attached to one another.

To be clear, the two different containers should preferably be transitioned between in a smooth fashion as in the case of an Accordion.

enter image description here

Upvotes: 3

Views: 929

Answers (1)

fabian
fabian

Reputation: 82461

Place the "standard" content and content for the slider (a HBox containing a button and the slider content) in a StackPane and use a animation to set translateX in a way such that the slider moves in and out of view:

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

Upvotes: 6

Related Questions