JavaFX - 鼠标悬停时自动隐藏 window
JavaFX - auto hide window on mouse over
目标
我需要创建一个 javafx 舞台,它在鼠标移到它上面时隐藏,但在鼠标不在我的舞台上时显示。 我的舞台应该,
- 当我将鼠标指针放在它上面时隐藏
- 当鼠标指针位于除我的舞台
以外的任何屏幕位置时显示
- 隐藏时允许click/focus通过它
问题
虽然这看起来很容易,但我不知道如何正确地完成它。是的,我们可以很容易地实现隐藏舞台的逻辑(使用鼠标事件监听器)。但是,在显示隐藏阶段时,隐藏阶段无法监听任何鼠标事件,这似乎很难。
- 我们可以在没有低级系统级逻辑的情况下实现这个吗?
- 如果是这样,我们该如何实施呢?任何人都可以提出一个好的方法吗?
- 如果我们需要使用低级系统范围的逻辑,我们如何在保持平台独立支持的同时做到这一点?
仅适用于 StageStyle.TRANSPARENT
。我能看到它与任何 StageStyle
一起工作的唯一选择是创建两个阶段。应该只有一个 hoverProperty 监听器。
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class App extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
StackPane stackPane = new StackPane();
Scene scene = new Scene(stackPane, 400, 400);
scene.setFill(null);
stage.initStyle(StageStyle.TRANSPARENT);
stage.setScene(scene);
stage.show();
ChangeListener<Boolean> listener = (observable, oldValue, newValue) -> {
if (newValue) {
stackPane.setStyle("-fx-background-color: rgb(0, 0, 0, 0.01);");
} else {
stackPane.setStyle("-fx-background-color: red;");
}
};
stackPane.hoverProperty().addListener(listener);
listener.changed(stackPane.hoverProperty(), null, stackPane.isHover());
}
}
在 JavaFX 中,您可以使用 javafx.scene.robot.Robot
获取鼠标指针位置。那么这份工作对你来说会很轻松。
例如,您可以这样做,
Bounds interfaceBounds = ...;
Robot robot = new Robot();
假设您有两个函数用于 hide/show 界面。
void hide() { ... }
void show() { ... }
然后你在另一个线程(计时器)中执行以下代码。
Point2D urMouse = robot.getMousePosition();
if( !interfaceBounds.contains( urMouse ) )
{
hide();
}else{
show();
}
目标
我需要创建一个 javafx 舞台,它在鼠标移到它上面时隐藏,但在鼠标不在我的舞台上时显示。 我的舞台应该,
- 当我将鼠标指针放在它上面时隐藏
- 当鼠标指针位于除我的舞台 以外的任何屏幕位置时显示
- 隐藏时允许click/focus通过它
问题
虽然这看起来很容易,但我不知道如何正确地完成它。是的,我们可以很容易地实现隐藏舞台的逻辑(使用鼠标事件监听器)。但是,在显示隐藏阶段时,隐藏阶段无法监听任何鼠标事件,这似乎很难。
- 我们可以在没有低级系统级逻辑的情况下实现这个吗?
- 如果是这样,我们该如何实施呢?任何人都可以提出一个好的方法吗?
- 如果我们需要使用低级系统范围的逻辑,我们如何在保持平台独立支持的同时做到这一点?
仅适用于 StageStyle.TRANSPARENT
。我能看到它与任何 StageStyle
一起工作的唯一选择是创建两个阶段。应该只有一个 hoverProperty 监听器。
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class App extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
StackPane stackPane = new StackPane();
Scene scene = new Scene(stackPane, 400, 400);
scene.setFill(null);
stage.initStyle(StageStyle.TRANSPARENT);
stage.setScene(scene);
stage.show();
ChangeListener<Boolean> listener = (observable, oldValue, newValue) -> {
if (newValue) {
stackPane.setStyle("-fx-background-color: rgb(0, 0, 0, 0.01);");
} else {
stackPane.setStyle("-fx-background-color: red;");
}
};
stackPane.hoverProperty().addListener(listener);
listener.changed(stackPane.hoverProperty(), null, stackPane.isHover());
}
}
在 JavaFX 中,您可以使用 javafx.scene.robot.Robot
获取鼠标指针位置。那么这份工作对你来说会很轻松。
例如,您可以这样做,
Bounds interfaceBounds = ...;
Robot robot = new Robot();
假设您有两个函数用于 hide/show 界面。
void hide() { ... }
void show() { ... }
然后你在另一个线程(计时器)中执行以下代码。
Point2D urMouse = robot.getMousePosition();
if( !interfaceBounds.contains( urMouse ) )
{
hide();
}else{
show();
}