使用 FXML 文件和场景构建器将 Swing 内容嵌入到 JavaFX 应用程序中
Embedding a Swing content into a JavaFX application with FXML file and scene builder
我正在尝试将一个用 Swing 编写的组件(它是 JPanel)放入 JavaFX 应用程序中。我设法使用此网站上显示的代码来做到这一点:click here
但我正在使用 FXML 文件和场景生成器构建我的应用程序。我试图将我的 Swing 组件放在带有 SwingNode 的 Pane 容器上(如下图所示):
但不幸的是,我没能做到。我到处都在寻找,但没有发现任何对我有用的东西。
我是 JavaFX 的新手,使用场景生成器对我来说非常重要。
这就是我想要做的事情吗?
我的考验:
Main.JAVA
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Letter Recognition with Neural Networks");
primaryStage.setScene(new Scene(root, 1150, 650));
primaryStage.setResizable(false);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller.JAVA
package application;
import application.gui.DrawingPanel;
import javafx.embed.swing.SwingNode;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javax.swing.*;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
@FXML
private Pane pane;
@FXML
private SwingNode swingNode;
@Override
public void initialize(URL location, ResourceBundle resources) {
swingNode = new SwingNode();
pane = new Pane();
createAndSetSwingDrawingPanel(swingNode);
pane.getChildren().add(swingNode);
}
public void createAndSetSwingDrawingPanel(final SwingNode swingNode) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
swingNode.setContent(new DrawingPanel(400, 400 , 20));
}
});
}
}
FXML 文件:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.embed.swing.SwingNode?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>
<GridPane gridLinesVisible="true" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.60">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Pane fx:id="pane" prefHeight="200.0" prefWidth="200.0">
<children>
<SwingNode fx:id="swingNode" />
</children>
</Pane>
<Button mnemonicParsing="false" prefHeight="39.0" prefWidth="80.0" text="Click" GridPane.rowIndex="2">
<font>
<Font size="18.0" />
</font>
</Button>
</children>
</GridPane>
swing 节点已经是窗格的子节点,因为在 FXML 中,<SwingNode>
元素位于 <children>
元素内,位于 <Pane>
元素内。所以你不应该在控制器中第二次将它添加到窗格的子节点。
此外,FXMLLoader
将控制器中的 pane
和 swingNode
字段初始化为对应于 FXML 文件创建的值(这是注释的重点他们 @FXML
)。初始化注释为 @FXML
.
的字段总是错误的
所以您在 initialize
方法中所需要的只是
@Override
public void initialize(URL location, ResourceBundle resources) {
createAndSetSwingDrawingPanel(swingNode);
}
最后,您似乎缺少 FXML 文件中的 <fx:controller>
属性。在 Scene Builder 中,展开最左下角的 "controller" 面板,然后在 "Controller Class" 字段中输入 application.Controller
。
我正在尝试将一个用 Swing 编写的组件(它是 JPanel)放入 JavaFX 应用程序中。我设法使用此网站上显示的代码来做到这一点:click here
但我正在使用 FXML 文件和场景生成器构建我的应用程序。我试图将我的 Swing 组件放在带有 SwingNode 的 Pane 容器上(如下图所示):
但不幸的是,我没能做到。我到处都在寻找,但没有发现任何对我有用的东西。
我是 JavaFX 的新手,使用场景生成器对我来说非常重要。 这就是我想要做的事情吗?
我的考验:
Main.JAVA
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Letter Recognition with Neural Networks");
primaryStage.setScene(new Scene(root, 1150, 650));
primaryStage.setResizable(false);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller.JAVA
package application;
import application.gui.DrawingPanel;
import javafx.embed.swing.SwingNode;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javax.swing.*;
import java.net.URL;
import java.util.ResourceBundle;
public class Controller implements Initializable {
@FXML
private Pane pane;
@FXML
private SwingNode swingNode;
@Override
public void initialize(URL location, ResourceBundle resources) {
swingNode = new SwingNode();
pane = new Pane();
createAndSetSwingDrawingPanel(swingNode);
pane.getChildren().add(swingNode);
}
public void createAndSetSwingDrawingPanel(final SwingNode swingNode) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
swingNode.setContent(new DrawingPanel(400, 400 , 20));
}
});
}
}
FXML 文件:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.embed.swing.SwingNode?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>
<GridPane gridLinesVisible="true" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.60">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Pane fx:id="pane" prefHeight="200.0" prefWidth="200.0">
<children>
<SwingNode fx:id="swingNode" />
</children>
</Pane>
<Button mnemonicParsing="false" prefHeight="39.0" prefWidth="80.0" text="Click" GridPane.rowIndex="2">
<font>
<Font size="18.0" />
</font>
</Button>
</children>
</GridPane>
swing 节点已经是窗格的子节点,因为在 FXML 中,<SwingNode>
元素位于 <children>
元素内,位于 <Pane>
元素内。所以你不应该在控制器中第二次将它添加到窗格的子节点。
此外,FXMLLoader
将控制器中的 pane
和 swingNode
字段初始化为对应于 FXML 文件创建的值(这是注释的重点他们 @FXML
)。初始化注释为 @FXML
.
所以您在 initialize
方法中所需要的只是
@Override
public void initialize(URL location, ResourceBundle resources) {
createAndSetSwingDrawingPanel(swingNode);
}
最后,您似乎缺少 FXML 文件中的 <fx:controller>
属性。在 Scene Builder 中,展开最左下角的 "controller" 面板,然后在 "Controller Class" 字段中输入 application.Controller
。