有跟踪阶段的方法吗?

时间:2016-01-08 13:53:06

标签: javafx focus scene stage

我希望跟踪焦点节点,以便在该节点上的用户不活动后执行某些操作。但专注于我的应用程序意味着整个应用程序中只有一个焦点节点(应用程序有很多阶段,而且它们的创建不受我的控制。我也不能强迫我公司的不同部门在创建后使用注册表来注册阶段它们)。

E.g。我有一个聚焦组件scene.focusOwnerProperty()的属性,我可以跟踪Stage是否是stage.focusedProperty(),但我正在搜索检索所有阶段的方式。

你知道吗?

3 个答案:

答案 0 :(得分:0)

我找到了解决方案。 com.sun.javafx.stage.StageHelper.getStages()列出所有阶段。

答案 1 :(得分:0)

您可以使用Window[] windows = Window.getWindows();这是Public Api的一部分,对我来说很好。

答案 2 :(得分:0)

谢谢你的回答。我写了一个类,它提供了一种简单的方法来跟踪当前关注的节点和“聚焦”场景。 “聚焦”意味着聚焦舞台的重点组成部分。如果我的代码中有任何错误,如果您发现并通知我,我将不胜感激。


    import javafx.beans.property.ReadOnlyObjectProperty;
    import javafx.beans.property.ReadOnlyObjectWrapper;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.scene.Node;
    import javafx.scene.Scene;
    import javafx.stage.Stage;

    import com.sun.javafx.stage.StageHelper;

    /**
     * Tracks focused component among all {@link Stage}'s. Currently this is singleton but it will make service
     * out of it.
     *
     * @author created: kszymanek on 8 sty 2016 15:19:32
     */
    public class GlobalFocusTracker
    {
        private static final GlobalFocusTracker INSTANCE = new GlobalFocusTracker();
        /**
         * tracks stage list and each stage and registers {@link #sceneListener} on
         * the focused stage
         */
        private StagesListener stagesListener;
        /**
         * tracks scene of the focused stage and registers
         * {@link #focusOwnerListener} on it
         */
        private SceneListener sceneListener;
        private FocusOwnerListener focusOwnerListener;
        private ReadOnlyObjectWrapper focusedNodeProperty = new ReadOnlyObjectWrapper();
        private ReadOnlyObjectWrapper focusedSceneProperty = new ReadOnlyObjectWrapper();

        private GlobalFocusTracker()
        {
        }

        public static GlobalFocusTracker getInstance()
        {
            return INSTANCE;
        }

        /**
         * @return current {@link Scene} from the currently focused {@link Stage}
         */
        public ReadOnlyObjectProperty focusedSceneProperty()
        {
            init();
            return focusedSceneProperty.getReadOnlyProperty();
        }

        /**
         * @return focused node among all stages. There could be one focus owner at
         *         the time. If end user focuses some other application there would
         *         be no focus node.
         */
        public ReadOnlyObjectProperty focusedNodeProperty()
        {
            init();
            return focusedNodeProperty.getReadOnlyProperty();
        }

        private void init()
        {
            if(stagesListener == null)
            {
                stagesListener = new StagesListener();
                sceneListener = new SceneListener();
                focusOwnerListener = new FocusOwnerListener();
                stagesListener.register();
            }
        }

        private class StagesListener implements ListChangeListener, ChangeListener
        {
            private ObservableList stages;

            @Override
            public void onChanged(javafx.collections.ListChangeListener.Change aChange)
            {
                while(aChange.next())
                {
                    if(aChange.wasRemoved())
                    {
                        for(Stage stage : aChange.getRemoved())
                        {
                            stage.focusedProperty().removeListener(this);
                        }
                    }
                    if(aChange.wasAdded())
                    {
                        for(Stage stage : aChange.getAddedSubList())
                        {
                            stage.focusedProperty().addListener(this);
                        }
                    }
                }
            }

            @Override
            public void changed(ObservableValue aObservable, Boolean aOld, Boolean aNew)
            {
                Stage focusedStage = null;
                for(Stage stage : stages)
                {
                    if(stage.isFocused())
                    {
                        focusedStage = stage;
                    }
                }
                sceneListener.register(focusedStage);
            }

            public void register()
            {
                if(stages == null)
                {
                    stages = StageHelper.getStages();
                    stages.addListener(this);
                    for(Stage stage : stages)
                    {
                        stage.focusedProperty().addListener(this);
                        if(stage.isFocused())
                        {
                            sceneListener.register(stage);
                        }
                    }
                }
            }

        }

        private class SceneListener implements ChangeListener
        {
            private Stage stage;

            @Override
            public void changed(ObservableValue aObservable, Scene aOld, Scene aNew)
            {
                focusOwnerListener.register(aNew);
            }

            /**
             * @param aStage is {@code null} protected
             */
            public void register(Stage aStage)
            {
                if(aStage != stage)
                {
                    unregister();
                    stage = aStage;
                    if(aStage != null)
                    {
                        aStage.sceneProperty().addListener(this);
                        focusOwnerListener.register(aStage.getScene());
                    }
                }
            }

            public void unregister()
            {
                if(stage != null)
                {
                    focusOwnerListener.unregister();
                    stage.sceneProperty().removeListener(this);
                    stage = null;
                }
            }
        }

        private class FocusOwnerListener implements ChangeListener
        {
            private Scene scene;

            @Override
            public void changed(ObservableValue aObservable, Node aOld, Node aNew)
            {
                focusedNodeProperty.set(aNew);
            }

            /**
             * @param aScene can be {@code null} in such case it is only an equivalent
             *           of {@link #unregister()}
             */
            public void register(Scene aScene)
            {
                if(scene != aScene)
                {
                    unregister();
                    scene = aScene;
                    focusedSceneProperty.set(aScene);
                    if(aScene != null)
                    {
                        focusedNodeProperty.set(aScene.getFocusOwner());
                        aScene.focusOwnerProperty().addListener(this);
                    }
                }
            }

            public void unregister()
            {
                if(scene != null)
                {
                    focusedSceneProperty.set(null);
                    focusedNodeProperty.set(null);
                    scene.focusOwnerProperty().removeListener(this);
                    scene = null;
                }
            }
        }

    }