使用FXML文件和场景构建器将Swing内容嵌入到JavaFX应用程序中

时间:2017-01-13 14:09:09

标签: swing javafx fxml scenebuilder fxmlloader

我试图将一个用Swing编写的组件(它的JPanel)放入JavaFX应用程序中。我设法使用本网站上显示的代码:click here

但我正在使用FXML文件和场景构建器构建我的应用程序。我试图将我的Swing组件放在带有SwingNode的Pane容器上(如下图所示):

scene builder

但不幸的是,我没有设法做到这一点。我到处寻找,在我的案例中我没有找到任何有用的东西。

我对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>

1 个答案:

答案 0 :(得分:1)

swing节点已经是窗格的子节点,因为在FXML中,<SwingNode>元素内的<children>元素位于<Pane>元素内。因此,您不应该在控制器中第二次将其添加到窗格的子节点。

此外,FXMLLoader将控制器中的paneswingNode字段初始化为对应于FXML文件创建的值(这是注释它们的全部内容{ {1}})。初始化带注释@FXML的字段始终是错误的。

所以@FXML方法所需要的只是

initialize

最后,您似乎错过了FXML文件中的@Override public void initialize(URL location, ResourceBundle resources) { createAndSetSwingDrawingPanel(swingNode); } 属性。在Scene Builder中,展开最左下角的“controller”面板,然后在“Controller Class”字段中输入<fx:controller>