(See the next version here.)
Intro
I have this tiny JavaFX program that shows a 800x600 pixel canvas. You are supposed to drag the mouse within the canvas. When you are done dragging, the program will print in the standard output the number of frames per second.
For example, my system prints
196 frames in 1566 milliseconds, refresh rate of 125.15964240102171 Hz.
Code
com.github.coderodde.javafx.mouseupdaterate.MouseUpdateRateFinder.java:
package com.github.coderodde.javafx.mouseupdaterate;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
public final class MouseUpdateRateFinder extends Application {
private static final int SCREEN_WIDTH = 800;
private static final int SCREEN_HEIGHT = 600;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
Group root = new Group();
Canvas canvas = new Canvas(SCREEN_WIDTH, SCREEN_HEIGHT);
canvas.addEventHandler(MouseEvent.ANY, new MyMouseListener());
root.getChildren().add(canvas);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
private static final class MyMouseListener implements EventHandler<MouseEvent> {
private long mouseButtonEventStart;
private int frameCounter;
@Override
public void handle(MouseEvent t) {
EventType<? extends MouseEvent> eventType = t.getEventType();
if (eventType.equals(MouseEvent.MOUSE_PRESSED)) {
mouseButtonEventStart = System.currentTimeMillis();
frameCounter = 0;
} else if (eventType.equals(MouseEvent.MOUSE_RELEASED)) {
long duration = System.currentTimeMillis()
- mouseButtonEventStart;
System.out.println(
frameCounter
+ " frames in "
+ duration
+ " milliseconds, refresh rate of "
+ computeRefreshRate(duration, frameCounter)
+ " Hz.");
} else if (eventType.equals(MouseEvent.MOUSE_DRAGGED)) {
frameCounter++;
}
}
private double computeRefreshRate(long duration, int frameCounter) {
double t = ((double) duration) / 1000.0;
return ((double) frameCounter) / t;
}
}
}
Critique request
Is there any room for improvement? Please tell me anything.
1 Answer 1
Your start
doesn't actually throw any checked exceptions, so remove throw Exception
(don't worry; this doesn't break override compatibility).
Writing an "everything handler" that then switches on event type is an anti-pattern; just register three separate handlers. You can use the new(ish) Java method reference sugar for this purpose. It's not strictly necessary to have a separate class but it's probably a good idea to keep it out of separation of concerns.
Might as well use nanoTime()
instead of currentTimeMillis()
for higher precision.
Avoid repeated-concatenation formatting; instead just use printf
. When you do this, you should limit floating-point precision in your output.
Suggested
package com.github.coderodde.javafx.mouseupdaterate;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
public final class MouseUpdateRateFinder extends Application {
private static final int SCREEN_WIDTH = 800;
private static final int SCREEN_HEIGHT = 600;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Group root = new Group();
MyMouseListener listener = new MyMouseListener();
Canvas canvas = new Canvas(SCREEN_WIDTH, SCREEN_HEIGHT);
canvas.addEventHandler(MouseEvent.MOUSE_PRESSED, listener::handlePressed);
canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED, listener::handleDragged);
canvas.addEventHandler(MouseEvent.MOUSE_RELEASED, listener::handleReleased);
root.getChildren().add(canvas);
stage.setScene(new Scene(root));
stage.show();
}
private static final class MyMouseListener {
private long dragStartNs;
private int frameCounter;
public void handlePressed(MouseEvent t) {
dragStartNs = System.nanoTime();
frameCounter = 0;
}
public void handleDragged(MouseEvent t) {
frameCounter++;
}
public void handleReleased(MouseEvent t) {
double duration = 1e-9*(System.nanoTime() - dragStartNs);
System.out.printf(
"%d frames in %.2f s, refresh rate of %.1f Hz%n",
frameCounter, duration, frameCounter / duration);
}
}
}
Output
155 frames in 1.61 s, refresh rate of 96.0 Hz
184 frames in 1.46 s, refresh rate of 126.2 Hz
Explore related questions
See similar questions with these tags.