Reputation: 1
I am trying to create a very simple, easy-to-use program that actively reads and displays the position of the mouse. I have seen many tutorials that create programs that read the position of the mouse only when it is inside the window of the GUI application, or after hitting a button, but I want one that displays the position of the mouse in all areas of the screen. This is what I have:
import java.awt.MouseInfo;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class MouseCoordinates extends Application{
public static void main(String[] args) {
launch();
}
public void start(Stage primaryStage) throws Exception{
primaryStage.setTitle("Mouse Reader");
Label x = new Label();
Label y = new Label();
StackPane layout = new StackPane();
layout.getChildren().addAll(x, y);
Scene scene = new Scene(layout, 600, 500);
primaryStage.setScene(scene);
primaryStage.show ();
double mouseX = 1.0;
double mouseY = 1.0;
while(true){
mouseX = MouseInfo.getPointerInfo().getLocation().getX();
mouseY = MouseInfo.getPointerInfo().getLocation().getY();
x.setText("" + mouseX);
y.setText("" + mouseY);
}
}
}
I understand that this while-loop is the cause of the window crashing, but I can not figure out a way around it. Can anyone explain why I can not use a while-loop for JavaFX, as well as a way to solve this?
Upvotes: 0
Views: 902
Reputation: 131456
Your start()
method don't have any change to exit the loop and therefore to return as you defined an infinite loop : while(true){...}
without return
statement.
Why not use a Timeline
?
Timeline timeLine = new Timeline(new KeyFrame(Duration.seconds(1), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
mouseX = MouseInfo.getPointerInfo().getLocation().getX();
mouseY = MouseInfo.getPointerInfo().getLocation().getY();
x.setText("" + mouseX);
y.setText("" + mouseY);
}
}));
timeLine.setCycleCount(Timeline.INDEFINITE);
timeLine.play();
or with a lambda :
Timeline timeLine = new Timeline(new KeyFrame(Duration.seconds(1),
e -> {
mouseX = MouseInfo.getPointerInfo().getLocation().getX();
mouseY = MouseInfo.getPointerInfo().getLocation().getY();
x.setText("" + mouseX);
y.setText("" + mouseY);
}
));
timeLine.setCycleCount(Timeline.INDEFINITE);
timeLine.play();
Another way to address your requirement could be using addEventFilter( MouseEvent.MOUSE_MOVED)
on the StackPane
object :
layout.addEventFilter(MouseEvent.MOUSE_MOVED, e -> {
x.setText("" + e.getScreenX());
y.setText("" + e.getScreenY());
});
The MouseEvent
class provides both X and Y absolute position on the device and
on the source component :
getScreenX()
Returns absolute horizontal position of the event.
getScreenY()
Returns the absolute vertical y position of the event
getX();
Horizontal position of the event relative to the origin of the MouseEvent's source.
getY();
Vertical position of the event relative to the origin of the MouseEvent's source.
Upvotes: 5