JavaFX2用户空闲检测

JavaFX2用户空闲检测,java,javafx,javafx-2,idle-processing,Java,Javafx,Javafx 2,Idle Processing,我正在尝试使用JavaFX作为UI制作一个简单的Java事务应用程序 我现在要做的是从我的应用程序中检测用户空闲状态,该应用程序有1个主阶段和多个场景。 示例:如果用户空闲3分钟,则返回主菜单。 我已经在Web上尝试了一些关于如何检测JavaFX空闲状态的例子,但是我发现的总是一个函数出现在所有场景中的空闲状态检测方法(我认为)对于事务应用程序来说是危险的(EX:Apple在事务处理过程中检测空闲状态)。br/> 是否可以在每个场景中检测用户空闲状态?怎么做 谢谢 编辑: 我已经尝试过的示例:


我正在尝试使用JavaFX作为UI制作一个简单的Java事务应用程序
我现在要做的是从我的应用程序中检测用户空闲状态,该应用程序有1个主阶段和多个场景。

示例:如果用户空闲3分钟,则返回主菜单。

我已经在Web上尝试了一些关于如何检测JavaFX空闲状态的例子,但是我发现的总是一个函数出现在所有场景中的空闲状态检测方法(我认为)对于事务应用程序来说是危险的(EX:Apple在事务处理过程中检测空闲状态)。br/> 是否可以在每个场景中检测用户空闲状态?怎么做
谢谢

编辑:

我已经尝试过的示例:


我真的不明白你对交易行为的看法。事务与数据有关,您的事务行为应该在数据级别定义,并且不应该受到UI中发生的事情的影响。换句话说,即使用户空闲导致UI重置,您的原子行为也应该完成或回滚

也许这会有帮助。(注意,在这些示例中我使用了Java8代码,但如果需要,您可以相当容易地使其符合JavaF2.2。)这遵循了Tomas Mikula的一般方法,即它使用
时间线来实现空闲检查。我没有使用Tomas的FX定时器包装器,但如果您愿意,您当然可以这样做。此类封装了一个监视用户是否空闲的监视器。您可以注册任何节点(或场景)和事件类型:如果该类型的事件发生在该节点(或场景)上,则确定用户不是空闲的。如果指定的时间已过,且未发生任何已注册事件,则将执行提供的runnable(在FX应用程序线程上)。这使您可以灵活地创建多个监控器(如果需要),并在每个监控器上注册一个或多个节点

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.scene.Node;
import javafx.scene.Scene;

import javafx.util.Duration;

public class IdleMonitor {

    private final Timeline idleTimeline ;

    private final EventHandler<Event> userEventHandler ;

    public IdleMonitor(Duration idleTime, Runnable notifier, boolean startMonitoring) {
        idleTimeline = new Timeline(new KeyFrame(idleTime, e -> notifier.run()));
        idleTimeline.setCycleCount(Animation.INDEFINITE);

        userEventHandler = e -> notIdle() ; 

        if (startMonitoring) {
            startMonitoring();
        }
    }

    public IdleMonitor(Duration idleTime, Runnable notifier) {
        this(idleTime, notifier, false);
    }

    public void register(Scene scene, EventType<? extends Event> eventType) {
        scene.addEventFilter(eventType, userEventHandler);
    }

    public void register(Node node, EventType<? extends Event> eventType) {
        node.addEventFilter(eventType, userEventHandler);
    }

    public void unregister(Scene scene, EventType<? extends Event> eventType) {
        scene.removeEventFilter(eventType, userEventHandler);
    }

    public void unregister(Node node, EventType<? extends Event> eventType) {
        node.removeEventFilter(eventType, userEventHandler);
    }

    public void notIdle() {
        if (idleTimeline.getStatus() == Animation.Status.RUNNING) {
            idleTimeline.playFromStart();
        }
    }

    public void startMonitoring() {
        idleTimeline.playFromStart();
    }

    public void stopMonitoring() {
        idleTimeline.stop();
    }
}

你的问题很不清楚。您能展示一下您尝试过的解决方案并更清楚地解释为什么它不适合您吗?我想在JavaFX2.0中也这样做,然后如何在主类中传递runnable?你能帮助我吗?我被困在这里
IdleMonitor IdleMonitor=new IdleMonitor(持续时间.秒(30),“*******”true)只需使用
Runnable
的实现来代替。
import javafx.application.Application;
import javafx.event.Event;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

public class IdleTest extends Application {

    @Override
    public void start(Stage primaryStage) {

        StackPane root = new StackPane();

        Parent mainUI = buildMainUI();
        Scene scene = new Scene(root, 350, 150);
        Parent startUI = buildStartUI(() -> root.getChildren().setAll(mainUI));
        root.getChildren().add(startUI);

        IdleMonitor idleMonitor = new IdleMonitor(Duration.seconds(30),
                () -> root.getChildren().setAll(startUI), true);
        idleMonitor.register(scene, Event.ANY);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private Parent buildStartUI(Runnable start) {
        Button button = new Button("Start");
        button.setOnAction(e -> start.run());
        StackPane root = new StackPane(button);
        return root ;
    }

    private Parent buildMainUI() {
        TabPane tabPane = new TabPane();
        Tab tab1 = new Tab("One");
        Parent tab1Content = buildTabUI("Tab 1");
        Parent tab1StartContent = buildStartUI(() -> tab1.setContent(tab1Content));
        tab1.setContent(tab1StartContent);
        IdleMonitor tab1IdleMonitor = new IdleMonitor(Duration.seconds(5), 
                () -> tab1.setContent(tab1StartContent), true);
        tab1IdleMonitor.register(tab1Content, Event.ANY);

        Tab tab2 = new Tab("Two");
        Parent tab2Content = buildTabUI("Tab 2") ;
        Parent tab2StartContent = buildStartUI(() -> tab2.setContent(tab2Content));
        tab2.setContent(tab2StartContent);
        IdleMonitor tab2IdleMonitor = new IdleMonitor(Duration.seconds(10),
                () -> tab2.setContent(tab2StartContent), true);
        tab2IdleMonitor.register(tab2Content, Event.ANY);

        tabPane.getTabs().addAll(tab1, tab2);
        return tabPane ;
    }

    private Parent buildTabUI(String text) {
        Button button = new Button("Click here");
        button.setOnAction(e -> System.out.println("Click in "+text));
        VBox content = new VBox(10, new Label(text), new TextField(), button);
        content.setAlignment(Pos.CENTER);
        return content ;
    }

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