Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javafx titledpane animation speed

Is there a way to set the animation speed of a titledpane? I couldn't find anything. In fact there are two issues. First: The animation of the expanding is faster than the expanding of the content itself. You see that the circle is slightly slower than the bar from the second titledpane is moving down.

Second: How to change the speed of both of them. I need them at the same speed, because it looks weird.

Here is a small example for testing purposes: package test;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.stage.Stage;

public class TestClass extends Application{

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

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


    VBox vb = new VBox();


    {
    TitledPane tp = new TitledPane();
    System.out.println(tp.getContextMenu());
    tp.setContent(new Circle(100));
    tp.setText("asfadf");

    tp.expandedProperty().addListener(new ChangeListener<Boolean>() {
        @Override
        public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {

                System.out.println("expand " + newValue);

        }
    });

    vb.getChildren().add(tp);
    }

    vb.getChildren().add(new Line(0, 0, 100, 0));

    {
        TitledPane tp = new TitledPane();
        tp.setContent(new Circle(100));
        tp.setText("asfadf");
        tp.expandedProperty().addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {

                    System.out.println("expand " + newValue);

            }
        });

        vb.getChildren().add(tp);
        }

    vb.setStyle("-fx-background-color: gray");



    Scene scene = new Scene(vb,500,500);

    primaryStage.setScene(scene);

    primaryStage.show();

}
}
like image 507
blaster Avatar asked Nov 10 '22 02:11

blaster


1 Answers

Short answer: There's no API to change the duration.

However, there are two ways to achieve it anyway:

Alternative #1: Reflection

The duration is defined in the static final field com.sun.javafx.scene.control.TitledPaneSkin.TRANSITION_DURATION. Using reflection, you can change its value but this is really bad. Not only because that's a dirty hack, but also because TitledPaneSkin is Oracle internal API that is subject to change anyway. Also, this does not fix the issue with the different speeds:

  private static void setTitledPaneDuration(Duration duration) throws NoSuchFieldException, IllegalAccessException {
    Field durationField = TitledPaneSkin.class.getField("TRANSITION_DURATION");

    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(durationField, durationField.getModifiers() & ~Modifier.FINAL);

    durationField.setAccessible(true);
    durationField.set(TitledPaneSkin.class, duration);
  }

Alternative #2: Set your own skin

To be on the safe side, you could create and use your own skin (start by copying the existing one) using titledPane.setSkin(). This way you can also fix the different speed, which is basically caused by linear vs. ease interpolation - but that's quite some work.

like image 121
Michel Jung Avatar answered Dec 08 '22 05:12

Michel Jung