javajavafxmouseeventfxml

How to detect 'onMouseMoved' on the entire scene?


I'm trying to detect if mouse is moving over the entire scene or not to close the app after 15min of inactivity.

In the example I have an Anchorpane occupying the entire scene with an OnMouseMoved event on it.

All movements are detected expected passing over the tabPane, why ?

How can I managed to detect all movements on the scene whatever the node is hovered ?

here are the files :

MoveTest.java

public class MoveTest extends Application {
    public static void main(String[] args) {
        launch(args);
    }

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

    void loadIhm(Stage stage) throws URISyntaxException {
        URL location = MouseTestCtrl.class.getResource("/application/mouseTest.fxml");
        FXMLLoader loader = new FXMLLoader(location);

        try {   
            AnchorPane root = loader.load();    

            stage.setScene(new Scene(root));
            stage.show();
        } catch (IOException e) {
            throw new RuntimeException("Problème FXML : mouseTest.fxml");
        }
    }
}

MouseTestCtrl

public class MouseTestCtrl {
    @FXML
    void moveDetected(MouseEvent event) {
        System.out.println("moving");
    }
}

mouseTest.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Text?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onMouseMoved="#moveDetected" prefHeight="644.0" prefWidth="883.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MouseTestCtrl">
    <children>
        <Pane layoutX="81.0" layoutY="70.0" prefHeight="499.0" prefWidth="730.0" style="-fx-border-color: black;">
            <children>
                <TabPane layoutX="11.0" layoutY="212.0" prefHeight="251.0" prefWidth="681.0" tabClosingPolicy="UNAVAILABLE">
                    <tabs>
                        <Tab text="Untitled Tab 1">
                            <content>
                                <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
                            </content>
                        </Tab>

                        <Tab text="Untitled Tab 2">
                            <content>
                                <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
                            </content>
                        </Tab>
                    </tabs>
                </TabPane>

                <Label layoutX="14.0" layoutY="4.0" text="Pane" />
                <GridPane layoutX="372.0" layoutY="88.0" prefHeight="75.0" prefWidth="198.0" style="-fx-border-color: black;">
                    <columnConstraints>
                        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                    </columnConstraints>

                    <rowConstraints>
                        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                    </rowConstraints>

                    <children>
                        <Text strokeType="OUTSIDE" strokeWidth="0.0" text="3" GridPane.columnIndex="1" GridPane.rowIndex="1" />
                        <Text strokeType="OUTSIDE" strokeWidth="0.0" text="5" GridPane.rowIndex="2" />
                        <Text strokeType="OUTSIDE" strokeWidth="0.0" text="6" GridPane.rowIndex="1" />
                        <Text strokeType="OUTSIDE" strokeWidth="0.0" text="2" GridPane.columnIndex="1" />
                        <Text strokeType="OUTSIDE" strokeWidth="0.0" text="4" GridPane.columnIndex="1" GridPane.rowIndex="2" />
                        <Text strokeType="OUTSIDE" strokeWidth="0.0" text="1" />
                    </children>
                </GridPane>

                <Label layoutX="434.0" layoutY="34.0" text="gridpane" />
                <AnchorPane layoutX="58.0" layoutY="44.0" prefHeight="127.0" prefWidth="198.0" style="-fx-border-color: black;">
                    <children>
                        <Label layoutX="15.0" layoutY="6.0" text="Anchor" />
                    </children>
                </AnchorPane>
            </children>
        </Pane>

        <Label layoutX="14.0" layoutY="14.0" text="Anchor" />
    </children>
</AnchorPane>

Solution

  • The solution proposed by Slaw works perfectly

    theScene.addEventFilter(MouseEvent.MOUSE_MOVED, e -> { ... }). 
    

    Although you may want to listen for MouseEvent.ANY or even InputEvent.ANY instead, as user activity typically consists of more than just mouse-moved events (e.g., mouse clicks, mouse drags, key presses, etc.).

    Also, if you want, you can add that filter to the stage instead of the scene