gpt4 book ai didi

JavaFX 编辑 FXML 文档中的 WebView

转载 作者:行者123 更新时间:2023-11-30 08:54:35 25 4
gpt4 key购买 nike

我的目标是能够使用 Controller 类将 html 内容放入 fxml 文档中的 WebView 对象中。我的 FXML 文档中有其他对象,如按钮和图像,我希望 WebView 只是 GUI 的一部分。我可以使用 Controller 类将内容放入 FXML 文档的 TextArea 中。为 WebView 做这个有点棘手,因为它需要一个 WebEngine 来配合它。我知道如何在没有 FXML 文档的情况下自行启动 WebView,但有人知道我的目标是否可以实现吗?

这是我在 Controller 类中的尝试,但我得到一个调用目标异常:

public class FXMLDocumentController implements Initializable {

@FXML
private Label label;
WebEngine engine;

@FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
label.setText("Hello World!");
}

//access WebView in FXML document
@FXML WebView mywebview; //mywebview is the fxid
public void displayWeb() {
engine = mywebview.getEngine();
final String hellohtml = "chang.htm"; //HTML file to view in web view
URL urlHello = getClass().getResource(hellohtml);
engine.load(urlHello.toExternalForm());
}

@Override
public void initialize(URL url, ResourceBundle rb) {
displayWeb();
}

}

最佳答案

这是一个巧妙的概念(至少如果我理解你的要求的话:-)。我喜欢这个。感谢您想到它。

在重新阅读您的问题时,我可能完全误解了它...如果是这样,我想您可以无视我的回答。

在 FXML 中内联指定 HTML 内容

不幸的是,WebView 是最终的,因此您不能只扩展 WebView 以将内容加载方法添加到可以在 FXML 中指定的元素。

解决方案是围绕 WebView 提供一个小型包装类,FXML 可以将其实例化并将内容设置到其中。我选择让包装器类继承 StackPane,这样包装器就是一个节点,并且可以在任何您可能想使用节点的地方用 FXML 实例化。

您也许可以使用 Builder 类而不是像我这样的包装类,但是关于为 FXML 执行此操作的文档非常稀少甚至不存在,所以我没有尝试。

为方便起见,将嵌入的 html 内容包装在 CDATA construct 中.然后你不必转义所有的html字符并且可以离开< , > , 和其他的而不是将这些字符重新编码为 &lt; , &gt;

Embedded WebView

embeddedwebview/embedded-webview.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.VBox?>
<?import embeddedwebview.EmbeddedWebView?>
<VBox xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
prefHeight="150.0" prefWidth="220.0">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<EmbeddedWebView fx:id="embeddedWebView">
<content>
<![CDATA[
<h3>Embedded WebView</h3>
<p>HTML content inline in FXML</p>
]]>
</content>
</EmbeddedWebView>
</VBox>

embeddedwebview/EmbeddedWebViewApp.java

package embeddedwebview;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class EmbeddedWebViewApp extends Application {
@Override
public void start(Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"embedded-webview.fxml"
)
);
Pane pane = loader.load();

stage.setScene(new Scene(pane));
stage.show();
}

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

embeddedwebview/EmbeddedWebView.java

import javafx.scene.layout.StackPane;
import javafx.scene.web.WebView;

/**
* A WebView which has getters and setters for content or a document url.
*
* Usage in FXML element is:
*
* EITHER by specifying a url to a html document:
*
* <EmbeddedWebView fx:id="embeddedWebView" url="/embeddedwebview/embedded.html">
*
* OR by specifying CDATA escaped html content:
*
* <EmbeddedWebView fx:id="embeddedWebView">
* <content>
* <![CDATA[
* <h3>Embedded WebView</h3>
* <p>HTML content inline in FXML</p>
* ]]>
* </content>
* </EmbeddedWebView>
*
*/
public class EmbeddedWebView extends StackPane {

final private WebView webView;

// For space efficiency, an alternate implementation could just
// rely on the content in the WebView itself rather than
// duplicating the content here, but it was simple to implement with a duplicate.
private String content;

private String url;

public EmbeddedWebView() {
webView = new WebView();
getChildren().add(webView);
}

public String getContent() {
return content;
}

/**
* Loads html content directly into the webview.
* @param content a html content string to load into the webview.
*/
public void setContent(String content) {
this.content = content;
webView.getEngine().loadContent(content);
}

public String getUrl() {
return url;
}

/**
* Loads content into the WebView from a given url.
* The allowed url types are http, https and file.
*
* Additionally, content can be loaded from a classpath resource.
* To be loaded from the classpath, the url must start with a / character
* and specify the full resource path to the html
* (i.e., relative resource path specifiers are not allowed).
*
* @param url the location of the html document to be loaded.
*/
public void setUrl(String url) {
if ( url == null || ! (url.startsWith("/") || url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:"))) {
throw new IllegalArgumentException("url must start with one of http: file: https: or /");
}

this.url = url;

if (url.startsWith("/")) {
webView.getEngine().load(
EmbeddedWebView.class.getResource(url).toExternalForm()
);
} else {
webView.getEngine().load(
url
);
}
}
}

引用 html 文档的替代用法。

将上述 fxml 中的 EmbeddedWebView 元素替换为以下内容:

<EmbeddedWebView fx:id="embeddedWebView" url="/embeddedwebview/embedded.html"/>

embeddedwebview/embedded.html

<!doctype html>

<html lang="en">
<head>
<meta charset="utf-8">
</head>

<body>
<h3>Embedded WebView</h3>
<p>HTML content inline in FXML</p>
</body>
</html>

So does the setUrl function set the global variabe url which getUrl returns?

url 成员是 EmbeddedWebView 的本地成员,而不是应用程序范围内的全局成员,但是,是的,您有大致的想法,setURL()是一个 setter ,FXML 通过反射查找它以在 EmbeddedWebView 中设置 url,您稍后可以使用 public getURL() 从任何类中检索 EmbeddedWebView 中的 url。功能。

关于JavaFX 编辑 FXML 文档中的 WebView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29353547/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com