JavaFX虚拟键盘与节点重叠 [英] JavaFX virtual keyboard overlaps nodes

查看:106
本文介绍了JavaFX虚拟键盘与节点重叠的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于在Windows 8.1上在支持触摸的PC上使用虚拟键盘的问题.当使用java开关对文本字段进行聚焦时,我设法显示了虚拟键盘:

i have a question about using virtual keyboard on touch supported pc with Windows 8.1. I have managed to show the virtual keyboard when textfield is focused with java switch:

-Dcom.sun.javafx.isEmbedded=true -Dcom.sun.javafx.virtualKeyboard=javafx

我在 JavaFX虚拟键盘未显示上找到了解决方法 1 .

I found how to that on JavaFX Virtual Keyboard doesn't show1.

但是当键盘显示出来时,它与键盘下方的节点重叠.

But when the keyboard show's up, it overlapps nodes below the keyboard.

根据我的阅读, http://docs.oracle.com/javase/8/javafx/user-interface-tutorial/embed.htm ,它不应该那样工作.

According to what I read, http://docs.oracle.com/javase/8/javafx/user-interface-tutorial/embed.htm, it should't be working like that.

有人有处理此类问题的经验吗?

Does anyone have any experience with that kind of problem?

当我运行测试应用程序时,它以全屏显示,并且正在显示嵌入式虚拟键盘,因为文本字段具有焦点.在这种情况下,直到我隐藏"键盘后,文本字段才可见.我不确定这是否是正确的方法,所以我需要帮助.

When i run the test application it shows in full screen and embedded virtual keyboard is showing, becasue the textfield has focus. The textfield in this case is not visible until i "hide" the keyboard. I am not sure that this is the right approach so i need help please.

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();
    }
}

点击字段后的用户名或密码

After click in field username or password

如果有任何建议,我将不胜感激.预先感谢.

I would be grateful for any advice. Thanks in advance.

推荐答案

正如我在第一个答案中指出的那样,虚拟键盘嵌入在PopupWindow中,在不同的阶段创建,并显示在顶部您当前阶段的状态.

As I've already pointed out in my first answer, the virtual keyboard is embedded in a PopupWindow, created in a different stage, and displayed on top of your current stage.

选项-Dcom.sun.javafx.vk.adjustwindow=true起作用,移动主舞台,以便控件可见并且没有重叠.

The option -Dcom.sun.javafx.vk.adjustwindow=true works, moving the main stage so the control is visible and there is no overlapping.

但是,当此输入控件位于主界面的底部时,它将向上移动到屏幕的中心,从而留下一个很大的空白区域,以显示后面的内容.

But when this input control is located at the bottom of the main stage, this is moved up to the center of the screen leaving a big empty gap that shows whatever is behind.

第二个答案提供了一种解决方案,可以将主舞台仅移动所需的距离,而没有任何间隙,同时还要考虑虚拟键盘的淡入/淡出动画.

This second answer gives a solution to move the main stage just the required distance, without any gap, also taking into account the fade in/out animations of the virtual keyboard.

对于初学者,在我们的场景中,我们在中心添加Button,在底部添加TextField.通过两个控件,我们可以轻松更改焦点并显示/隐藏键盘.

For starters, in our scene, we add a Button on the center, and the TextField on the bottom. With two controls we can change the focus easily and show/hide the keyboard.

为了最大化该阶段,我将使用getVisualBounds(),以便任务栏可见.

To maximize the stage I'll use getVisualBounds(), so the taskbar can be visible.

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 一样,我们将使用不赞成使用的方法来获取有效的窗口:

We need to find the new stage when it's shown. In the same way as Scenic View, we'll use a deprecated method to get a valid window:

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;
}

当文本字段获得焦点时,我们将调用此方法:

We'll call this method when the textfield gets the focus:

    ...
    stage.show();

    tfComment.focusedProperty().addListener((ob,b,b1)->{
        if(keyboard==null){
            keyboard=getPopupWindow();
        }
    });
}

一旦有了窗口,我们就可以聆听其位置的变化并相应地移动主舞台:

Once we have the window, we can listen to changes in its position and move the main stage accordingly:

    ....
    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);
                });
            });
        }
    });
}

请注意,代替上移舞台,另一个选择是调整其大小(如果控件内有足够的空间).

Note that instead of moving up the stage, another option will be resizing it (if there is enough space within the controls).

在这种情况下,文本字段将成为焦点,并且虚拟键盘将完全显示:

This will be the case where the textfield gets the focus and the virtual keyboard is fully shown:

这篇关于JavaFX虚拟键盘与节点重叠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆