我正在编写一个程序,当它启动时,其中一个锚窗格会在光标位置打开。我已经用一个方法做到了,该方法在initialize()中调用,并且工作正常。问题是,主要是,当我隐藏 PrimaryStage 或关闭它,并再次实例化一个要显示的舞台时,它将不再获得光标位置,并且 UI 始终出现在与第一次。就像控制器一直在运行一样。有人知道为什么会发生吗?我该如何解决这个问题? 有一种方法可以在锚窗格启动或可见时更改控制器中的位置?或者停止那个继续运行的东西?保持其打开的解决方案对于性能来说会更好。我使用 Jnativehook 来调用它,还有 scenebuilder。 谢谢。 JDK 21、JAVAFX 21.0.1、JNativeHook 2.2.2.
主要:
package MRE;
import java.io.IOException;
import com.github.kwhat.jnativehook.GlobalScreen;
import com.github.kwhat.jnativehook.NativeHookException;
import com.github.kwhat.jnativehook.keyboard.NativeKeyEvent;
import com.github.kwhat.jnativehook.keyboard.NativeKeyListener;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Main extends Application implements NativeKeyListener{
private Stage primaryStage;
public static boolean shortcutIsPressed;
public static void main(String[] args) {
Platform.setImplicitExit(false);
nativeKeyListener();
}
@Override
public void start(Stage primaryStage) throws Exception {
}
public void testStage() throws IOException {
primaryStage = new Stage();
Parent root = FXMLLoader.load(getClass().getResource("/MRE/test.fxml"));
Scene scene = new Scene(root);
//SHOW STAGE
primaryStage.setAlwaysOnTop(true);
primaryStage.setScene(scene);
primaryStage.show();
}
//JNATIVEHOOK///////////////////////////////////////////////////////////////////////
public void nativeKeyPressed(NativeKeyEvent e) {
// System.out.println("Key Pressed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
Platform.runLater( () -> {
if (e.getKeyCode() == NativeKeyEvent.VC_F5) {
shortcutIsPressed = true;
// System.out.println("F5: " + isPressed);
if(shortcutIsPressed = true) {
if(primaryStage == null) {
try {
testStage();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
} );
}
public void nativeKeyReleased(NativeKeyEvent e) {
System.out.println("Key Released: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
Platform.runLater( () -> {
if (e.getKeyCode() == NativeKeyEvent.VC_F5) {
shortcutIsPressed = false;
if(primaryStage != null) {
primaryStage.hide();
primaryStage = null;
// Platform.exit();
}
}
});
}
public void nativeKeyTyped(NativeKeyEvent e) {
// System.out.println("Key Typed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
}
public static void nativeKeyListener() {
//NATIVEKEYLISTENER
try {
GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());
System.exit(1);
}
GlobalScreen.addNativeKeyListener(new Main());
}
}
控制器:
package MRE;
import java.io.IOException;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
public class Controller {
@FXML
private AnchorPane aPaneInside;
@FXML
private AnchorPane aPaneOutside;
@FXML
private Button btn;
public void initialize() throws IOException {
setUiPosition();
}
public void setUiPosition() {
aPaneInside.setLayoutX(Utils.cursorPoint.getX()-aPaneInside.getPrefWidth()/2);
aPaneInside.setLayoutY(Utils.cursorPoint.getY()-aPaneInside.getPrefHeight()/2);
}
}
实用工具:
package MRE;
import java.awt.MouseInfo;
import java.awt.Point;
public class Utils {
public static Point cursorPoint = MouseInfo.getPointerInfo().getLocation();
}
FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="aPaneOutside" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1080.0" prefWidth="1920.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="MRE.Controller">
<children>
<AnchorPane fx:id="aPaneInside" layoutX="860.0" layoutY="440.0" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: blue;">
<children>
<Button fx:id="btn" layoutX="74.0" layoutY="88.0" mnemonicParsing="false" text="Button" />
</children>
</AnchorPane>
</children>
</AnchorPane>
模块信息:
module MRE {
requires javafx.fxml;
requires javafx.graphics;
requires javafx.controls;
requires java.desktop;
requires com.github.kwhat.jnativehook;
opens MRE to javafx.graphics, javafx.fxml;
}
public static Point cursorPoint =
MouseInfo.getPointerInfo().getLocation();
是一个静态成员 -> 仅当首次加载
Utils
类时才会设置。
使用
Utils
中的静态方法来代替:
public static Point getCursorPoint() {
return MouseInfo.getPointerInfo().getLocation();
}.
每当您调用它时,都会获得当前光标位置。