我正在尝试在 JavaFX 中创建自定义组件并将其导入 SceneBuilder。我创建了一个仅包含该自定义组件的项目,并且我希望能够将该组件导入到 SceneBuilder 中。我希望在 SceneBuilder 选择中看到
CustomComponent
。然而,SceneBuilder中的自定义组件选择结果是空白的!我该如何解决这个问题?请注意,如果我使用SceneBuilder 中的 JavaFX 自定义组件使用中描述的示例,它可以完美运行。
我没有希望 SceneBuilder 正确显示的特定 FXML 文件,我只想将此自定义组件(名为
CustomComponent
)导入到 SceneBuilder 中。
这是我所有的项目文件。 (注:本项目的Artifact ID为
custom-component
)
src/main/java/com/remmymilkyway/customcomponent/CustomComponent.java
package com.remmymilkyway.customcomponent;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import java.net.URL;
public class CustomComponent extends Region {
private final WebView webView;
private final WebEngine webEngine;
public CustomComponent() {
this.webView = new WebView();
this.webEngine = webView.getEngine();
URL url = getClass().getResource("/monaco_editor.html");
if (url != null) {
webEngine.load(url.toExternalForm());
}
this.getChildren().add(webView);
}
public String getEditorContent() {
return (String) webEngine.executeScript("getEditorValue()");
}
public void setEditorContent(String newValue) {
String escapedContent = newValue.replace("'", "\\'").replace("\n", "\\n");
webEngine.executeScript("setEditorValue('" + escapedContent + "');");
}
public void setFontFamily(String fontFamily) {
webEngine.executeScript("setFontFamily('" + fontFamily + "');");
}
public void setFontSize(int fontSize) {
webEngine.executeScript("setFontSize(" + fontSize + ");");
}
public void setLanguage(String languageIdentifier) {
webEngine.executeScript("setLanguage('" + languageIdentifier + "');");
}
@Override
protected void layoutChildren() {
webView.setPrefSize(getWidth(), getHeight());
webView.resize(getWidth(), getHeight());
}
}
src/main/java/resources/monaco_editor.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Monaco Editor in JavaFX</title>
<script src="monaco-editor/min/vs/loader.js"></script>
<style>
body, html {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
}
#container {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
require.config({ paths: { 'vs': 'monaco-editor/min/vs' }});
require(['vs/editor/editor.main'], function () {
var editor = monaco.editor.create(document.getElementById('container'), {
language: 'cpp',
automaticLayout: true
});
window.getEditorValue = function () {
return editor.getValue();
}
window.setEditorValue = function (newValue) {
editor.setValue(newValue);
}
window.setFontFamily = function(fontFamily) {
editor.updateOptions({
fontFamily: fontFamily
});
};
window.setFontSize = function(fontSize) {
editor.updateOptions({
fontSize: fontSize
});
};
window.setLanguage = function(language) {
monaco.editor.setModelLanguage(editor.getModel(), language);
};
});
</script>
</body>
</html>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.remmymilkyway</groupId>
<artifactId>custom-component</artifactId>
<version>1.0-SNAPSHOT</version>
<name>custom-component</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>5.10.2</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>22.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>22.0.1</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-web</artifactId>
<version>22.0.1</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<source>22</source>
<target>22</target>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<executions>
<execution>
<!-- Default configuration for running with: mvn clean javafx:run -->
<id>default-cli</id>
<configuration>
<mainClass>
com.remmymilkyway.customcomponent/com.remmymilkyway.customcomponent.HelloApplication
</mainClass>
<launcher>app</launcher>
<jlinkZipName>app</jlinkZipName>
<jlinkImageName>app</jlinkImageName>
<noManPages>true</noManPages>
<stripDebug>true</stripDebug>
<noHeaderFiles>true</noHeaderFiles>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Monaco Editor 分发文件下载到文件夹
src/main/resources/monaco-editor
。
我运行了命令
mvn install
并尝试通过单击 从存储库手动添加库 按钮并导入版本 1.0-SNAPSHOT
将项目导入到 SceneBuilder 中。如图所示:
当我单击 ADD JAR 按钮时,我选择了一个空选项。
我尝试过此操作,但也无法导入依赖 WebView 与 SceneBuilder 22 配合使用的组件。
尽管 SceneBuilder 将与内置的 WebView 控件一起使用(它有一个可以使用该控件的组件),但它无法与包含 WebView 的自定义组件一起使用,至少从我的测试来看是这样。 如果您愿意,您可以向 Gluon 提交功能请求以添加支持。
您可以使用更简单的情况来使其失败。
具有这两个组件的项目将只能看到导入
ButtonComponent
,而不是 WebViewComponent
。
src/main/java/com/example/customcomponent/ButtonComponent.java
package com.example.customcomponent;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
public class ButtonComponent extends Pane {
public ButtonComponent() {
super(new Button("Button"));
}
}
src/main/java/com/example/customcomponent/WebViewComponent.java
package com.example.customcomponent;
import javafx.scene.layout.Pane;
import javafx.scene.web.WebView;
public class WebViewComponent extends Pane {
public WebViewComponent() {
super(new WebView());
}
}
src/main/java/module-info.java
module com.example.customcomponent {
requires javafx.web;
exports com.example.customcomponent;
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>editor-component</artifactId>
<version>1.0-SNAPSHOT</version>
<name>editor-component</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>22</maven.compiler.source>
<maven.compiler.target>22</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-web</artifactId>
<version>22.0.2</version>
</dependency>
</dependencies>
</project>
从本地 maven 存储库导入 SceneBuilder(在项目上运行
mvn install
后):
<groupId>com.example</groupId>
<artifactId>editor-component</artifactId>
<version>1.0-SNAPSHOT</version>
可用组件: