我有一个关于在Windows 8.1上使用触摸支持的电脑上使用虚拟键盘的问题。当使用java开关重点关注textfield时,我已设法显示虚拟键盘:
-Dcom.sun.javafx.isEmbedded=true -Dcom.sun.javafx.virtualKeyboard=javafx
我在JavaFX Virtual Keyboard doesn't show 1上找到了相应的内容。
但是当键盘显示时,它会覆盖键盘下方的节点。
根据我所读到的http://docs.oracle.com/javase/8/javafx/user-interface-tutorial/embed.htm,它不应该像那样工作。
有没有人有这种问题的经验?
当我运行测试应用程序时,它会全屏显示并显示嵌入式虚拟键盘,因为文本字段具有焦点。在这种情况下,文本字段是不可见的,直到我隐藏"键盘。我不确定这是正确的方法所以我需要帮助。
java -Dcom.sun.javafx.isEmbedded=true -Dcom.sun.javafx.virtualKeyboard=javafx application.TestVKB
public class TestVKB extends Application{
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) throws Exception {
TextField tfComment = new TextField();
tfComment.setPromptText("Enter comment");
BorderPane borderPane = new BorderPane();
borderPane.setBottom(tfComment);
Scene scene = new Scene(borderPane);
stage.setScene(scene);
stage.setMaximized(true);
stage.show();
}
}
点击字段用户名或密码后
如果有任何建议,我将不胜感激。提前谢谢。
答案 0 :(得分:7)
正如我在第一个回答中已经指出的那样,虚拟键盘嵌入在PopupWindow
中,在不同的阶段创建,并显示在当前舞台的顶部。
选项-Dcom.sun.javafx.vk.adjustwindow=true
有效,移动主舞台以便控件可见并且没有重叠。
但是当这个输入控制位于主舞台的底部时,它会向上移动到屏幕的中心,留下一个很大的空隙,显示背后的内容。
第二个答案提供了一个解决方案,可以将主舞台移动到所需的距离,没有任何间隙,同时还考虑了虚拟键盘的淡入/淡出动画。
对于初学者,在我们的场景中,我们在中心添加Button
,在底部添加TextField
。使用两个控件,我们可以轻松更改焦点并显示/隐藏键盘。
要最大化阶段,我将使用getVisualBounds()
,因此可以看到任务栏。
private PopupWindow keyboard;
private final Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds();
private final Rectangle2D bounds = Screen.getPrimary().getBounds();
private final double taskbarHeight=bounds.getHeight()-visualBounds.getHeight();
@Override
public void start(Stage stage) {
TextField tfComment = new TextField();
tfComment.setPromptText("Enter comment");
BorderPane borderPane = new BorderPane(new Button("Click"));
borderPane.setBottom(tfComment);
Scene scene = new Scene(borderPane);
stage.setScene(scene);
stage.setX(visualBounds.getMinX());
stage.setY(visualBounds.getMinY());
stage.setWidth(visualBounds.getWidth());
stage.setHeight(visualBounds.getHeight());
stage.show();
}
我们需要在显示时找到新阶段。与Scenic View一样,我们将使用弃用的方法来获取有效窗口:
private PopupWindow getPopupWindow() {
@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;
}
当文本字段获得焦点时,我们将调用此方法:
...
stage.show();
tfComment.focusedProperty().addListener((ob,b,b1)->{
if(keyboard==null){
keyboard=getPopupWindow();
}
});
}
一旦我们有了窗口,我们就可以听取其位置的变化并相应地移动主舞台:
....
stage.show();
//findWindowExecutor.execute(new WindowTask());
tfComment.focusedProperty().addListener((ob,b,b1)->{
if(keyboard==null){
keyboard=getPopupWindow();
keyboard.yProperty().addListener(obs->{
System.out.println("wi "+keyboard.getY());
Platform.runLater(()->{
double y = bounds.getHeight()-taskbarHeight-keyboard.getY();
stage.setY(y>0?-y:0);
});
});
}
});
}
请注意,不是向上移动舞台,而是另一个选项是调整大小(如果控件中有足够的空间)。
这将是文本字段获得焦点并完全显示虚拟键盘的情况:
答案 1 :(得分:2)
基本上,虚拟键盘嵌入在PopupWindow
中,在不同的舞台上创建,并显示在当前舞台的顶部,在屏幕的底部,无论InputControl
在哪里触发键盘所在的位置。
您可以在FXVKSkin
课程上看到:
winY.set(screenBounds.getHeight() - VK_HEIGHT);
但是,在此之后,您可以找到:
if (vkAdjustWindow) {
adjustWindowPosition(attachedNode);
}
因此,您可以使用另一个命令行选项移动舞台,以便节点(本例中为文本字段)位于屏幕的中心,您可以键入而不重叠:
-Dcom.sun.javafx.vk.adjustwindow=true
请注意,当文本字段失去焦点时,键盘将被隐藏,舞台将再次移动到其原始位置:
restoreWindowPosition(oldNode);
我已经成功测试了这个选项,但是当你在屏幕底部有文本字段时,这会将你的舞台底部移动到屏幕的中心,两个阶段之间留下很大的差距(你会看到任何东西)你有背景)。
我设法在新舞台上添加一个听众,并根据需要调整位置。如果你有兴趣我可以发布它。
修改强>
如果舞台最大化,请注意此命令行选项不起作用。一个简单的解决方案是:
Rectangle2D bounds = Screen.getPrimary().getBounds();
stage.setX(bounds.getMinX());
stage.setY(bounds.getMinY());
stage.setWidth(bounds.getWidth());
stage.setHeight(bounds.getHeight());
stage.show();
答案 2 :(得分:0)
我喜欢这个解决方案,但在我的情况下,我更喜欢使用show方法移动键盘 getPopupWindow 我在textfield上创建了一个监听器并直接改变了键盘的位置。
textField.focusedProperty().addListener((ob, b, b1) -> {
if (keyboard == null) {
keyboard = getPopupWindow();
keyboard.setHideOnEscape(Boolean.TRUE);
keyboard.setAutoHide(Boolean.TRUE);
keyboard.centerOnScreen();
keyboard.requestFocus();
keyboard.sizeToScene();
}
Platform.runLater(() -> {
keyboard.setY(**NEW_POSITION_OF_KEYBOARD**);
});
});