更改 JavaFX 虚拟键盘的显示
Change display of JavaFX virtual keyboard
我的开发系统包含一台 Windows 电脑,上面连接了三个显示器。第三个显示器是我的触摸屏显示器。我已指示 Windows 使用控制面板中的 "Tablet PC Settings" 将此屏幕用作我的触摸屏显示器。
我的应用程序是一个包含 TextField 的简单 JavaFX 触摸屏应用程序。为了显示虚拟键盘,我将以下设置设置为 true:
- -Dcom.sun.javafx.isEmbedded=真
- -Dcom.sun.javafx.touch=真
- -Dcom.sun.javafx.virtualKeyboard=javafx
我的问题是键盘可以显示,但显示在错误的显示器上。它显示在主显示器上,而不是设置为触摸显示器的第三台显示器上。
有没有办法在当前系统配置下在我的触摸显示器上显示虚拟键盘?例如,通过告诉键盘它的所有者应用程序在哪里,以便它显示在正确的显示器上?
了解如何将显示键盘的显示器更改为显示应用程序的显示器。
将更改侦听器附加到文本字段的焦点 属性。执行更改侦听器时,检索键盘弹出窗口。然后找到显示应用程序的监视器的活动屏幕边界,并将键盘 x 坐标移动到该位置。
通过将 autoFix 设置为 true,键盘将确保它(部分)不在您的显示器之外,设置 autoFix 将自动调整 y 坐标。如果不设置autoFix,还需要手动设置y坐标。
@FXML
private void initialize() {
textField.focusedProperty().addListener(getKeyboardChangeListener());
}
private ChangeListener getKeyboardChangeListener() {
return new ChangeListener() {
@Override
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
PopupWindow keyboard = getKeyboardPopup();
// Make sure the keyboard is shown at the screen where the application is already shown.
Rectangle2D screenBounds = getActiveScreenBounds();
keyboard.setX(screenBounds.getMinX());
keyboard.setAutoFix(true);
}
};
}
private PopupWindow getKeyboardPopup() {
@SuppressWarnings("deprecation")
final Iterator<Window> windows = Window.impl_getWindows();
while (windows.hasNext()) {
final Window window = windows.next();
if (window instanceof PopupWindow) {
if (window.getScene() != null && window.getScene().getRoot() != null) {
Parent root = window.getScene().getRoot();
if (root.getChildrenUnmodifiable().size() > 0) {
Node popup = root.getChildrenUnmodifiable().get(0);
if (popup.lookup(".fxvk") != null) {
return (PopupWindow)window;
}
}
}
return null;
}
}
return null;
}
private Rectangle2D getActiveScreenBounds() {
Scene scene = usernameField.getScene();
List<Screen> interScreens = Screen.getScreensForRectangle(scene.getWindow().getX(), scene.getWindow().getY(),
scene.getWindow().getWidth(), scene.getWindow().getHeight());
Screen activeScreen = interScreens.get(0);
return activeScreen.getBounds();
}
我的开发系统包含一台 Windows 电脑,上面连接了三个显示器。第三个显示器是我的触摸屏显示器。我已指示 Windows 使用控制面板中的 "Tablet PC Settings" 将此屏幕用作我的触摸屏显示器。
我的应用程序是一个包含 TextField 的简单 JavaFX 触摸屏应用程序。为了显示虚拟键盘,我将以下设置设置为 true:
- -Dcom.sun.javafx.isEmbedded=真
- -Dcom.sun.javafx.touch=真
- -Dcom.sun.javafx.virtualKeyboard=javafx
我的问题是键盘可以显示,但显示在错误的显示器上。它显示在主显示器上,而不是设置为触摸显示器的第三台显示器上。
有没有办法在当前系统配置下在我的触摸显示器上显示虚拟键盘?例如,通过告诉键盘它的所有者应用程序在哪里,以便它显示在正确的显示器上?
了解如何将显示键盘的显示器更改为显示应用程序的显示器。
将更改侦听器附加到文本字段的焦点 属性。执行更改侦听器时,检索键盘弹出窗口。然后找到显示应用程序的监视器的活动屏幕边界,并将键盘 x 坐标移动到该位置。
通过将 autoFix 设置为 true,键盘将确保它(部分)不在您的显示器之外,设置 autoFix 将自动调整 y 坐标。如果不设置autoFix,还需要手动设置y坐标。
@FXML
private void initialize() {
textField.focusedProperty().addListener(getKeyboardChangeListener());
}
private ChangeListener getKeyboardChangeListener() {
return new ChangeListener() {
@Override
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
PopupWindow keyboard = getKeyboardPopup();
// Make sure the keyboard is shown at the screen where the application is already shown.
Rectangle2D screenBounds = getActiveScreenBounds();
keyboard.setX(screenBounds.getMinX());
keyboard.setAutoFix(true);
}
};
}
private PopupWindow getKeyboardPopup() {
@SuppressWarnings("deprecation")
final Iterator<Window> windows = Window.impl_getWindows();
while (windows.hasNext()) {
final Window window = windows.next();
if (window instanceof PopupWindow) {
if (window.getScene() != null && window.getScene().getRoot() != null) {
Parent root = window.getScene().getRoot();
if (root.getChildrenUnmodifiable().size() > 0) {
Node popup = root.getChildrenUnmodifiable().get(0);
if (popup.lookup(".fxvk") != null) {
return (PopupWindow)window;
}
}
}
return null;
}
}
return null;
}
private Rectangle2D getActiveScreenBounds() {
Scene scene = usernameField.getScene();
List<Screen> interScreens = Screen.getScreensForRectangle(scene.getWindow().getX(), scene.getWindow().getY(),
scene.getWindow().getWidth(), scene.getWindow().getHeight());
Screen activeScreen = interScreens.get(0);
return activeScreen.getBounds();
}