在用户第一次点击控件之前,尝试在WebView上执行requestFocus()不起作用。
我知道这一定是可能的,因为htmlEditor可以这样聚焦(我怀疑它是基于一个可信的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();
}
}
答案 0 :(得分:4)
requestFocus api只是一个焦点请求,它不能保证焦点。
有时其他JavaFX控件的内部实现会在您请求焦点之前或之后请求焦点,这会在requestFocus调用中没有任何效果。
通常,您可以通过将Platform.runLater包裹在Timeline中,或者使用KeyFrame {{3}}来延迟调用requestFocus,从而使requestFocus调用生效。
如果这些都不起作用,那么在WebView的requestFocus处理中可能存在一个错误,JavaFX团队可以在您提交的jira的上下文中解决该错误。
<强>更新强>
问题示例代码中的具体问题是,尽管WebView受到关注,但WebView中的可编辑内容元素并未集中。
我尝试将示例代码<html><head></head><body contenteditable='true'></body></html>
中的html加载到firefox中,它的行为与JavaFX WebView完全相同(即可编辑的内容元素在被点击之前没有被聚焦)。所以我不认为这是WebView的问题。
要使可编辑元素集中,您需要在需要聚焦时执行某些脚本,例如在javascript onload hook <body onLoad='document.body.focus();' contenteditable='true'/>
这是一个可执行的示例应用程序,它演示了对JavaFX WebView中可信元素的焦点行为的编程控制:
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();
}
}
答案 1 :(得分:3)
你可以这样关注HTMLEditor的webview:
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 view = (WebView) ((GridPane)((HTMLEditorSkin)editor.getSkin()).getChildren().get(0)).getChildren().get(2);
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));
});
}
}