无法以编程方式聚焦contenteditable的Webview

无法以编程方式聚焦contenteditable的Webview,webview,javafx,Webview,Javafx,在用户第一次单击控件之前,尝试在WebView上执行requestFocus()不会起作用 我知道这一定是可能的,因为htmlEditor可以以这种方式集中精力(我怀疑它是基于contenteditable WebView的) 我正在使用带有“contenteditable”的webview编写我自己的专用htmlEditor,我真的希望能够像使用标准htmlEditor一样对其进行关注 我相信这一定是Javafx的一个问题,我已经把它提交给了Jira,但我想知道是否有人能想到解决这个问题的办法

在用户第一次单击控件之前,尝试在WebView上执行requestFocus()不会起作用

我知道这一定是可能的,因为htmlEditor可以以这种方式集中精力(我怀疑它是基于contenteditable WebView的)

我正在使用带有“contenteditable”的webview编写我自己的专用htmlEditor,我真的希望能够像使用标准htmlEditor一样对其进行关注

我相信这一定是Javafx的一个问题,我已经把它提交给了Jira,但我想知道是否有人能想到解决这个问题的办法

更新:jira中的发行号:RT-21695

简短演示代码:

/* Demo webview */

public class WebViewConteneditableDemo extends Application {


String initialEditview = "<html><head>"
        + "</head><body contenteditable='true'>"
        +"</body></html>";

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    launch(args);
}

@Override
public void start(Stage primaryStage) {
    primaryStage.setTitle("Webview focus demo");


    final WebView editor = new WebView();

    Button btn = new Button();
    btn.setText("Test Webview focus");
    btn.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
           editor.requestFocus();
        }
    });

    BorderPane root = new BorderPane();
    root.setTop(btn);

    root.setCenter(editor);
    editor.getEngine().loadContent(initialEditview);

    primaryStage.setScene(new Scene(root, 500, 450));
    primaryStage.show();
}
/*演示Web视图*/
公共类WebViewContendedItableDemo扩展了应用程序{
字符串initialEditview=“”
+ ""
+"";
/**
*@param指定命令行参数
*/
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
公共无效开始(阶段primaryStage){
setTitle(“Webview焦点演示”);
最终WebView编辑器=新建WebView();
按钮btn=新按钮();
btn.setText(“测试Webview焦点”);
btn.setOnAction(新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent事件){
requestFocus();
}
});
BorderPane根=新的BorderPane();
根。setTop(btn);
root.setCenter(编辑器);
editor.getEngine().loadContent(initialEditview);
原始阶段。设置场景(新场景(根,500450));
primaryStage.show();
}
}

api只是对焦点的请求,不能保证焦点

有时,其他JavaFX控件的内部实现在您请求焦点之前或之后请求焦点,但最终在您的requestFocus调用中没有任何效果

通常,您可以通过将requestFocus调用包装在中或使用在延迟后调用requestFocus的

如果两者都不起作用,那么在WebView的requestFocus处理中可能有一个bug,JavaFX团队可以在您提交的jira的上下文中解决这个bug

更新

问题中示例代码中的具体问题是,尽管WebView是聚焦的,但WebView中的可编辑内容元素没有聚焦

我尝试将示例代码
中的html加载到firefox中,它的行为与JavaFX WebView完全相同(即,可编辑内容元素在被单击之前没有被关注)。所以我不认为这是WebView的问题

要使可编辑元素集中,需要在需要集中时执行一些脚本,例如在javascript onload钩子中

下面是一个可执行示例应用程序,它演示了对JavaFX WebView中contenteditable元素的焦点行为的编程控制:

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.event.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class WebViewEditable extends Application {
  String content = "<body bgcolor='cornsilk' onLoad='document.body.focus();' contenteditable='true'/>";
  public static void main(String[] args) { launch(args); }
  @Override public void start(Stage stage) {
    final WebView editor = new WebView();
    editor.getEngine().loadContent(content);

    Button webviewFocusButton = new Button("Focus on WebView");
    webviewFocusButton.setOnAction(new EventHandler<ActionEvent>() {
      @Override public void handle(ActionEvent event) {
        editor.getEngine().executeScript("document.body.focus()");
        editor.requestFocus();
      }
    });
    Button selfFocusButton = new Button("Focus on this Button");

    Label focusLabel = new Label();
    focusLabel.textProperty().bind(Bindings
      .when(editor.focusedProperty())
        .then("WebView has the focus.")
        .otherwise("WebView does not have the focus.")
    );
    focusLabel.setMaxWidth(Double.MAX_VALUE);
    focusLabel.setStyle("-fx-background-color: coral; -fx-padding: 5;");

    BorderPane layout = new BorderPane();
    layout.setTop(HBoxBuilder.create().spacing(10).children(webviewFocusButton, selfFocusButton).style("-fx-padding: 10; -fx-background-color: palegreen").build());
    layout.setCenter(editor);
    layout.setBottom(focusLabel);
    stage.setScene(new Scene(layout));
    stage.show();
  }
}
导入javafx.application.application;
导入javafx.beans.binding.Bindings;
导入javafx.event.*;
导入javafx.scene.scene;
导入javafx.scene.control.*;
导入javafx.scene.layout.*;
导入javafx.scene.web.WebView;
导入javafx.stage.stage;
公共类WebViewEditable扩展了应用程序{
字符串内容=”;
公共静态void main(字符串[]args){launch(args);}
@覆盖公共无效开始(阶段){
最终WebView编辑器=新建WebView();
editor.getEngine().loadContent(内容);
按钮webviewFocusButton=新按钮(“聚焦于WebView”);
webviewFocusButton.setOnAction(新的EventHandler(){
@重写公共无效句柄(ActionEvent事件){
editor.getEngine().executeScript(“document.body.focus()”);
requestFocus();
}
});
按钮自聚焦按钮=新按钮(“聚焦于此按钮”);
标签焦点标签=新标签();
focusLabel.textProperty().bind(绑定
.when(editor.focusedProperty())
。然后(“WebView拥有焦点。”)
。否则(“WebView没有焦点。”)
);
focusLabel.setMaxWidth(双倍最大值);
focusLabel.setStyle(“-fx背景色:珊瑚色;-fx填充:5;”);
BorderPane布局=新建BorderPane();
layout.setTop(HBoxBuilder.create().间距(10).子对象(webviewFocusButton,selfFocusButton).样式(“-fx填充:10;-fx背景颜色:淡绿色”).build());
布局.setCenter(编辑器);
布局。setBottom(焦点标签);
舞台场景(新场景(布局));
stage.show();
}
}

您可以通过以下方式聚焦HTMLEditor的Web视图:

import com.sun.javafx.scene.web.skin.HTMLEditorSkin;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.web.HTMLEditor;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class FocusTest extends Application {

    public static void main(final String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        final HTMLEditor editor = new HTMLEditor();
        final WebView editorView = (WebView) editor.lookup(".web-view");

        primaryStage.setScene(new Scene(editor));
        primaryStage.sizeToScene();
        primaryStage.show();

        Platform.runLater(() -> {
            view.fireEvent(new MouseEvent(MouseEvent.MOUSE_PRESSED, 100, 100, 200, 200, MouseButton.PRIMARY, 1, false, false, false, false, false, false, false, false, false, false, null));
            editor.requestFocus();
            view.fireEvent(new MouseEvent(MouseEvent.MOUSE_RELEASED, 100, 100, 200, 200, MouseButton.PRIMARY, 1, false, false, false, false, false, false, false, false, false, false, null));
        });
    }

}

还要添加Jira问题编号/链接。我无法复制您所指的问题,您能否添加一个简短的可编译示例来演示该问题。您可以看到,我使用了一个按钮来设置焦点,但您可以尝试以任何其他方式进行设置,在手动单击编辑器之前,它将无法工作。。。然后它就开始工作了。必须有一种方法以编程方式聚焦对象。我尝试了一个平台。runLater,一个计时器,甚至尝试了一个按钮,以确保它与时间无关。什么都不管用,但在你点击焦点后。。。如果你在webengine的document属性中添加一个监听器,并且在java中加载了requestFocus或者在webengine上运行executescript到Yes之后,我尝试了监听器,但什么都没有。但我还没有从javascript尝试过它。。。让我试试看…我现在已经发布了完整的演示代码。。。只是注意到它少了一些派对!这个解决方案非常有效。非常感谢您提供此代码的使用。使用Javafx是一件很愉快的事情。我已经更新了一个完整的工作示例。我在Mac/Linux/WinOkey上使用它,我将稍后或明天尝试:)谢谢