按下热键时,JavaFX应用程序无法获得焦点

时间:2017-05-22 17:19:04

标签: java javafx focus

按热键(ALT + SHIFT + V)时,焦点不会返回应用程序。 我使用JnativeHook作为全局键盘监听器。我尝试添加到阶段或节点requestFocus()toFront()中的任何一个,但这没有帮助。使用swing时的情况相同。还尝试了swingjavFX应用的设置模式 - 没有帮助。我可以选择添加java.awt.Robot,但我不确定这是更好的主意。 这是代码示例。

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.jnativehook.GlobalScreen;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;

import java.awt.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ShowStageTest extends Application{

    private static Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());

    private static final int WIDTH = 300;
    private static final int HEIGHT = 400;

    public static void main(String[] args) {
        logger.setLevel(Level.WARNING);

        Application.launch(ShowStageTest.class);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        Platform.setImplicitExit(false);

        primaryStage.setAlwaysOnTop(true);
        primaryStage.initStyle(StageStyle.UNDECORATED);
        primaryStage.focusedProperty().addListener((ov, t, t1) -> {
            if (t) {
                primaryStage.hide();
            }
        });

        ListView<String> itemList = new ListView<>();
        itemList.setPrefSize(WIDTH, HEIGHT - HEIGHT / 10);
        itemList.setFixedCellSize(HEIGHT / 10);

        TextField textField = new TextField();
        textField.setPrefSize(WIDTH, HEIGHT / 10);
        textField.setOnKeyPressed(ke -> {
            if (ke.getCode().equals(KeyCode.ENTER)) {
                itemList.getItems().add(0, textField.getText());
                textField.setText("");
            }
        });

        VBox box = new VBox(textField, itemList);
        box.setPrefSize(WIDTH, HEIGHT);

        Scene scene = new Scene(box, WIDTH, HEIGHT);
        primaryStage.setScene(scene);

        GlobalScreen.registerNativeHook();
        GlobalScreen.addNativeKeyListener(new NativeKeyListener() {
            @Override
            public void nativeKeyPressed(NativeKeyEvent e) {
                boolean isAltPressed = (e.getModifiers() & NativeKeyEvent.ALT_MASK) != 0;
                boolean isShiftPressed = (e.getModifiers() & NativeKeyEvent.SHIFT_MASK) != 0;

                if (e.getKeyCode() == NativeKeyEvent.VC_V && isShiftPressed && isAltPressed) {
                    Platform.runLater(() -> {
                        Point mouseLocation = MouseInfo.getPointerInfo().getLocation();

                        primaryStage.setX(mouseLocation.getX());
                        primaryStage.setY(mouseLocation.getY());
                        primaryStage.show();
                        primaryStage.toFront();
                    });
                }
            }

            @Override
            public void nativeKeyReleased(NativeKeyEvent nativeKeyEvent) {}
            @Override
            public void nativeKeyTyped(NativeKeyEvent nativeKeyEvent) {}
        });
    }
}

1 个答案:

答案 0 :(得分:0)

我认为您必须在app和应用程序的每个部分中使用API​​来编写所需的界​​面。 关于swing,您可以使用JFrame中的对话框窗口,还可以创建JPanel并添加{{1}}。