Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auto close JavaFX application due to innactivity

I want to close my JavaFX application if the user is inactive for a period of time. I have this code in Swing and I want to do the same in JavaFX. This class redirect the user to the login panel if no event happens during the time indicated.

import javax.swing.Timer;

public class AutoClose {

    private Timer timer;

    public AutoClose(JFrame centralpanel) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {

                Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {

                    @Override
                    public void eventDispatched(AWTEvent event) {
                        Object source = event.getSource();
                        if (source instanceof Component) {
                            Component comp = (Component) source;
                            Window win = null;
                            if (comp instanceof Window) {
                                win = (Window) comp;
                            } else {
                                win = SwingUtilities.windowForComponent(comp);
                            }
                            if (win == centralpanel) {
                                timer.restart();
                            }
                        }
                    }
                }, AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_WHEEL_EVENT_MASK);

                timer = new Timer(3600000, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {

                        centralpanel.dispose();

                        //Redirect to the login panel.
                        Login login = new Login();
                        login.setVisible(true);
                        timer.stop();
                        JOptionPane.showMessageDialog(null,"Connection closed due to inactivity");
                    }
                });
                timer.start();
            }
        });
    }
}
like image 812
Darkros Avatar asked Dec 01 '17 10:12

Darkros


2 Answers

Create a PauseTransition to trigger a delayed exit and add a event filter for InputEvents to all your scenes that restart the transition:

@Override
public void start(Stage primaryStage) throws IOException {
    Button button = new Button("abcde");
    StackPane root = new StackPane(button);
    Scene scene = new Scene(root, 400, 400);

    // create transition for logout
    Duration delay = Duration.seconds(10);
    PauseTransition transition = new PauseTransition(delay);
    transition.setOnFinished(evt -> logout());

    // restart transition on user interaction
    scene.addEventFilter(InputEvent.ANY, evt -> transition.playFromStart());

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

    transition.play();
}

private void logout() {
    // TODO: replace with logout code
    Platform.exit();
}

Note: It's important to use an event filter since events can be consumed before they reach an event handler.

like image 73
fabian Avatar answered Sep 25 '22 17:09

fabian


I have done this code and now it works correctly as I wanted.

public class AutoClose {
    private Timeline timer;

    public AutoClose(VBox mainPanel) {

        timer = new Timeline(new KeyFrame(Duration.seconds(3600), new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent evt) {
                Alert alert = new Alert(Alert.AlertType.INFORMATION);
                alert.setTitle("Inactivity");
                alert.setHeaderText("Connection closed due to inactivity");
                alert.show();

                try {
                    Stage mainWindowStage = Login.getPrimaryStage();

                    Parent root = FXMLLoader.load(getClass().getResource("/view/Login.fxml"));

                    Scene scene = new Scene(root);
                    mainWindowStage.setScene(scene);
                    mainWindowStage.show();

                    timer.stop();
                } catch (IOException ex) { 
                }
            }
        }));
        timer.setCycleCount(Timeline.INDEFINITE);
        timer.play();

        mainPanel.addEventFilter(MouseEvent.ANY, new EventHandler<Event>() {
            @Override
            public void handle(Event event) {
                timer.playFromStart();
            }
        });
    }
}
like image 27
Darkros Avatar answered Sep 24 '22 17:09

Darkros