当前位置: 首页 > 知识库问答 >
问题:

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

东门文斌
2023-03-14

我试图将一个用Swing编写的组件(它是JPanel)放入JavaFX应用程序中。我设法用这个网站上显示的代码做到了:点击这里

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

但不幸的是,我没能做到。我到处找,但在我的箱子里没有找到任何有用的东西。

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);
    }

}
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));
            }
        });
    }
}
<?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个答案

周浩淼
2023-03-14

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

此外,fxmlloader将把控制器中的窗格swingnode字段初始化为与FXML文件相对应创建的值(这就是注释它们的全部意义@FXML)。初始化注释为@fxml的字段总是错误的。

所以在initialize方法中只需要

@Override
public void initialize(URL location, ResourceBundle resources) {
    createAndSetSwingDrawingPanel(swingNode);
}

最后,FXML文件中似乎缺少 属性。在Scene Builder中,展开左下角的“Controller”面板,并在“Controller Class”字段中输入Application.Controller

 类似资料:
  • 我在javafx场景构建器中设计了一个用户界面,它在stackpane中有一个简单的按钮。我将控制器类命名为简单类。我已经保存了fxml作为simple.fxml.我在netbean中创建了一个控制器类,它只是在单击按钮时打印一些msg。 在NewFXBuilderJava中,我加载了simple。fxml。请在下面找到NewFXBuilder。java代码。 我的想法很简单。fxml,simpl

  • 请用简单的语言回答以上问题。如果可能的话,为我提供一些如何使用JavaFX的好教程。

  • 第一个问题:由于将集成到容器(BorderPane)中,它本身不需要容器。但是SceneBuilder只提供了将布局创建为容器的选项? 第二个问题:我可以手动创建,然后手动修改以包括。然后,我可以使用SceneBuilder毫无问题地加载borderpane.fxml文件。但是,当我现在更改标签的文本并选择“保存”时,修改的不是,而是如下所示: 新标签文本应该写入,而不是写入。 我想为我的GUI的

  • 问题内容: 我有一个应用程序,其中包含带有标题和菜单的HomeScene.fxml文件。HomeScene还具有dashboardPane,应在按下菜单按钮后对其进行动态更改。仪表板窗格内容应从另一个fxml文件加载,例如说“ FinancesPane.fxml”或“ SettingsPane.fxml”。 我正在尝试在HomeController中替换dashboardPane的内容: 我的Fi

  • 有人知道如何将JavaFX场景保存到可以由JavaFX FXMLLoader加载的FXML文件中吗? SceneBuilder允许这样做,但如果我手动构建场景,我如何将其保存到FXML文件中?

  • 我有一个很大的swing应用程序,我想把javafx嵌入其中。我多次尝试这样做(通过遵循oracle教程等),但只有在声明一个新的JFrame以使用JFXPanel组件时才成功。但是,我不想使用新的框架,我想将我的Javafx代码合并到swing应用程序的根JFrame中。 我们可以将javaFX组件嵌入到JPanel而不是JFrame中吗?如果答案是肯定的,为什么我没有成功?