2

シーンが表示されたときにディスパッチされるシーンまたはノードクラスのイベントリスナーを登録する方法が見つからないようです。

Sceneクラスを自己完結型にして、ビルダークラスを使用してそれらを構築し、表示されたときにアニメーションを起動できるようにします。たとえば、Applicationクラスで次のようなことができるようにしたいと思います...

public void start(Stage primaryStage) {
    primaryStage.setScene(AnimatedLoginSceneBuilder.create()
        .width(1024)
        .height(768)
        .frameRate(25)
        .build();
    )
    primaryStage.show();
}

私のAnimatedLoginSceneBuilderクラスは、シーンと、シーン内のいくつかのノードにバインドするアニメーションを作成します。ただし、ビルドメソッドを使用してのみシーンを返すことができます(アニメーションクラスは返しません)。たとえば、次のようになります...

public class AnimatedLoginSceneBuilder implements Builder<Scene> {
    // private members such as width, height and framerate
    // methods to set width, height and framerate (e.g. width(double width))

    public Scene build() {
        DoubleProperty x = new SimpleDoubleProperty();
        Text node = TextNodeBuilder...
        node.xProperty().bind(x);
        final Timeline animation = TimelineBuilder... // animate x
        return SceneBuilder.create()
           . // create my scene using builders (bar the node above)
           .build();
    }
}

しかし、アニメーションを再生する方法がないので、次のようなフックが必要です...

public class AnimatedLoginSceneBuilder ... {
    ...
    public Scene build() {
        ... 
        final Timeline animation = TimelineBuilder... // animate x
        return SceneBuilder.create()
            . // create scene declaratively
            .onShow(new EventHandler<SomeEvent>() {
                @Overide public void handleSomeEvent() {
                    animation.play();
                }
            .build()
    }

その後、シーンが表示されると、自動的に再生されます。質問することが多すぎますか?

1つの代替方法は、ビルダークラスに、オブジェクトにラップされたシーンとアニメーションの両方を返し、次のようなことを行うことです...

public void start(Stage primaryStage) {
    WrapperObj loginSceneWrapper = AnimatedLoginSceneBuilder.create()
       .width(1024)
       .height(768)
       .frameRate(25)
       .build();

    primaryStage.setScene(wrapperObj.getScene());
    primaryStage.show();
    wrapperObj.getAnimation().play();

しかし、これは私が望んでいることではありません。既存のシーン内から新しいシーンに変更できるようにしたいので、何も想定していません。たとえば、シーン内のイベントハンドラーでステージを新しいシーンに移行できるようにしたいので、primaryStage.setScene(新しいシーン)を呼び出すことができます。行きたい)。

何か案は?

私が見た中で最も近いのは、シーングラフのノードでWindowEvent.WINDOW_SHOWNをリッスンする方法ですか?しかし、この場合は機能しません。

4

1 に答える 1

1

"Showing" イベントは、javafx.​stage.Windowが表示されたときに発生します。window.setOnShowing()およびを使用して、適切なイベントのリスナーを設定できますwindow.setOnShown()。Scene はシーン グラフのコンテナーであり、表示/非表示に関するロジックはありません。

シーンの代わりにシーンのアニメートされたルート ノード (親またはそのサブクラスから拡張) を保存することをお勧めします。そして、次のようなルート変更イベントにリスナーを追加します

stage.getScene().rootProperty().addListener(new ChangeListener<MyAnimatedParent>() {
     @Override
     public void changed(ObservableValue<? extends MyAnimatedParent> observable, MyAnimatedParent oldValue, MyAnimatedParent newValue) {
         newValue.animate();
     }
 });
于 2012-11-30T16:15:25.640 に答える