我有一个关于在装有 Windows 8.1 的支持触控的电脑上使用虚拟键盘的问题。当文本字段以 java 开关为焦点时,我设法显示了虚拟键盘:
-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();
}
}
点击字段用户名或密码后
如有任何建议,我将不胜感激。提前致谢。
最佳答案
正如我在第一个回答中指出的那样,虚拟键盘嵌入在一个 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);
});
});
}
});
}
请注意,不是向上移动舞台,另一个选项是调整它的大小(如果控件中有足够的空间)。
这将是文本字段获得焦点并且虚拟键盘完全显示的情况:
关于JavaFX 虚拟键盘重叠节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27980788/