JavaFX 虚拟键盘重叠节点

标签 java javafx-8 virtual-keyboard

我有一个关于在装有 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();
    }
}

enter image description here

点击字段用户名或密码后 enter image description here

如有任何建议,我将不胜感激。提前致谢。

最佳答案

正如我在第一个回答中指出的那样,虚拟键盘嵌入在一个 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);
                });
            });
        }
    });
}

请注意,不是向上移动舞台,另一个选项是调整它的大小(如果控件中有足够的空间)。

这将是文本字段获得焦点并且虚拟键盘完全显示的情况:

Virtual keyboard

关于JavaFX 虚拟键盘重叠节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27980788/

相关文章:

java - 找不到资源文件

java - 从共享首选项获取值时出现空指针异常

Blackberry Playbook WebWorks 如何使文本字段打开不同的虚拟键盘?

c# - 为 Windows 10 开发自定义虚拟键盘

android 网络浏览器和虚拟键盘

java - 如何覆盖用 ClassLoader 实例化的类的方法

java - Wicket 口 1.5 与 1.4 相比

swing - 自 1.8.0_40 起,JavaFX swing 节点 D&D 失败

javafx-2 - Javafx 组合框样式

屏幕中央的 JavaFX 位置对话框和舞台