JavaFX检测计算机睡眠或休眠
JavaFX detect computer sleep or hibernate
我有一个 JavaFX 应用程序在计算机进入睡眠或休眠状态后出现 CPU 和内存问题。
在应用程序中,我使用每秒绘制两次的 Canvas。这可能会导致问题。我想知道是否有可能检测到计算机何时休眠,而不是重新绘制它。也许 canvas.isVisible() 已经在检查这个了?
只有当您的应用有焦点时,您才能绘画。
这可以通过在应用程序的主 window 不再具有焦点时暂停动画来实现。
您可以监控舞台的 focusedProperty()
以了解舞台何时获得焦点。
我 运行 使用 JavaFX 18 在 Mac (OS X 12.3) 上进行了一些测试,发现当计算机进入睡眠状态时(单击菜单中的苹果图标bar 和 select Sleep),焦点从应用程序中移除,这允许应用程序的动画在没有焦点时暂停。
示例应用程序
import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;
public class SleepyApp extends Application {
private long start;
private Counter continuousCounter = new Counter();
private Counter focusedCounter = new Counter();
@Override
public void start(Stage stage) throws Exception {
VBox layout = new VBox(10,
focusedCounter.getCounterLabel(),
continuousCounter.getCounterLabel()
);
layout.setPrefSize(80, 80);
layout.setAlignment(Pos.CENTER);
stage.setScene(new Scene(layout));
stage.show();
stage.focusedProperty().addListener((observable, wasFocused, isFocused) -> {
if (isFocused) {
focusedCounter.play();
} else {
focusedCounter.pause();
}
});
continuousCounter.play();
focusedCounter.play();
start = System.currentTimeMillis();
}
@Override
public void stop() throws Exception {
long stop = System.currentTimeMillis();
continuousCounter.stop();
focusedCounter.stop();
long elapsed = (stop - start) / 1_000;
System.out.println("Elapsed: " + elapsed + " seconds.");
System.out.println("Continuous Counter: " + continuousCounter.getCount() + " seconds.");
System.out.println("Focused Counter: " + focusedCounter.getCount() + " seconds.");
}
public static void main(String[] args) {
launch(args);
}
class Counter {
private final Timeline timeline;
private final IntegerProperty count;
private final Label counterLabel;
public Counter() {
count = new SimpleIntegerProperty(0);
counterLabel = new Label(count.asString().get());
counterLabel.textProperty().bind(
count.asString()
);
counterLabel.setStyle("-fx-font-size: 20px");
timeline = new Timeline(
new KeyFrame(
Duration.seconds(1),
e -> count.set(count.get() + 1)
)
);
timeline.setCycleCount(Timeline.INDEFINITE);
}
public int getCount() {
return count.get();
}
public Label getCounterLabel() {
return counterLabel;
}
public void play() {
timeline.play();
}
public void pause() {
timeline.pause();
}
public void stop() {
timeline.stop();
}
}
}
输出
在这种情况下,计算机休眠了 16 秒。
第一个数字是仅当应用程序获得焦点时每秒呈现的动画帧数。
第二个数字是每秒渲染一个动画帧的数量,无论应用程序是否具有焦点(和睡眠状态)。
Elapsed: 30 seconds.
Continuous Counter: 30 seconds.
Focused Counter: 14 seconds.
在isVisible()
node.isVisible()
不适用于这种情况。
这是对 isVisible 方法的描述:
Specifies whether this Node and any subnodes should be rendered as part of the scene graph. A node may be visible and yet not be shown in the rendered scene if, for instance, it is off the screen or obscured by another Node. Invisible nodes never receive mouse events or keyboard focus and never maintain keyboard focus when they become invisible.
如文档所示,节点可能可见但未显示在渲染场景中,计算机处于睡眠状态时会出现这种情况。
我有一个 JavaFX 应用程序在计算机进入睡眠或休眠状态后出现 CPU 和内存问题。
在应用程序中,我使用每秒绘制两次的 Canvas。这可能会导致问题。我想知道是否有可能检测到计算机何时休眠,而不是重新绘制它。也许 canvas.isVisible() 已经在检查这个了?
只有当您的应用有焦点时,您才能绘画。
这可以通过在应用程序的主 window 不再具有焦点时暂停动画来实现。
您可以监控舞台的 focusedProperty()
以了解舞台何时获得焦点。
我 运行 使用 JavaFX 18 在 Mac (OS X 12.3) 上进行了一些测试,发现当计算机进入睡眠状态时(单击菜单中的苹果图标bar 和 select Sleep),焦点从应用程序中移除,这允许应用程序的动画在没有焦点时暂停。
示例应用程序
import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;
public class SleepyApp extends Application {
private long start;
private Counter continuousCounter = new Counter();
private Counter focusedCounter = new Counter();
@Override
public void start(Stage stage) throws Exception {
VBox layout = new VBox(10,
focusedCounter.getCounterLabel(),
continuousCounter.getCounterLabel()
);
layout.setPrefSize(80, 80);
layout.setAlignment(Pos.CENTER);
stage.setScene(new Scene(layout));
stage.show();
stage.focusedProperty().addListener((observable, wasFocused, isFocused) -> {
if (isFocused) {
focusedCounter.play();
} else {
focusedCounter.pause();
}
});
continuousCounter.play();
focusedCounter.play();
start = System.currentTimeMillis();
}
@Override
public void stop() throws Exception {
long stop = System.currentTimeMillis();
continuousCounter.stop();
focusedCounter.stop();
long elapsed = (stop - start) / 1_000;
System.out.println("Elapsed: " + elapsed + " seconds.");
System.out.println("Continuous Counter: " + continuousCounter.getCount() + " seconds.");
System.out.println("Focused Counter: " + focusedCounter.getCount() + " seconds.");
}
public static void main(String[] args) {
launch(args);
}
class Counter {
private final Timeline timeline;
private final IntegerProperty count;
private final Label counterLabel;
public Counter() {
count = new SimpleIntegerProperty(0);
counterLabel = new Label(count.asString().get());
counterLabel.textProperty().bind(
count.asString()
);
counterLabel.setStyle("-fx-font-size: 20px");
timeline = new Timeline(
new KeyFrame(
Duration.seconds(1),
e -> count.set(count.get() + 1)
)
);
timeline.setCycleCount(Timeline.INDEFINITE);
}
public int getCount() {
return count.get();
}
public Label getCounterLabel() {
return counterLabel;
}
public void play() {
timeline.play();
}
public void pause() {
timeline.pause();
}
public void stop() {
timeline.stop();
}
}
}
输出
在这种情况下,计算机休眠了 16 秒。
第一个数字是仅当应用程序获得焦点时每秒呈现的动画帧数。
第二个数字是每秒渲染一个动画帧的数量,无论应用程序是否具有焦点(和睡眠状态)。
Elapsed: 30 seconds.
Continuous Counter: 30 seconds.
Focused Counter: 14 seconds.
在isVisible()
node.isVisible()
不适用于这种情况。
这是对 isVisible 方法的描述:
Specifies whether this Node and any subnodes should be rendered as part of the scene graph. A node may be visible and yet not be shown in the rendered scene if, for instance, it is off the screen or obscured by another Node. Invisible nodes never receive mouse events or keyboard focus and never maintain keyboard focus when they become invisible.
如文档所示,节点可能可见但未显示在渲染场景中,计算机处于睡眠状态时会出现这种情况。