如何将Swing JPanel嵌入JavaFX框架?

4

Integrating JavaFX 2.0 with Swing and SWT中有一段代码,可以允许您在Swing JFrame内嵌入JFXPanel。 我想知道是否有相反的操作,即将一个JPanel嵌入到ApplicationStage中,它们是与JFrame相当的东西,如Converting from Swing to JavaFX?中所述。

/**
 * Simple class demonstrating interoperability between Swing and JavaFX. This
 * class is adapted from the example provided in the Javadoc documentation for
 * {@code javafx.embed.swing.JFXPanel}.
 */
public class SwingJavaFxInteroperabilityDemo
{
   private static void initAndShowGUI()
   {
      // This method is invoked on Swing thread
      final JFrame frame = new JFrame("JavaFX / Swing Integrated");
      final JFXPanel fxPanel = new JFXPanel();
      frame.add(fxPanel);
      frame.setVisible(true);

      Platform.runLater(new Runnable()
      {
         @Override
         public void run()
         {
            initFX(fxPanel);
         }
      });
   }

   private static void initFX(JFXPanel fxPanel)
   {
      // This method is invoked on JavaFX thread
      final Scene scene = TextIntegrationSceneCreator.createTextScene();
      fxPanel.setScene(scene);
   }

   public static void main(String[] arguments)
   {
      SwingUtilities.invokeLater(new Runnable()
      {
         @Override
         public void run()
         {
            initAndShowGUI();
         }
      });
   }   
}
1个回答

4

您可以使用SwingNode将Swing内容放置到JavaFX节点中。

示例应用程序

在先前链接的SwingNode文档中有一个示例应用程序:

image

import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

import javax.swing.*;

public class SwingFx extends Application {

    @Override
    public void start(Stage stage) {
        final SwingNode swingNode = new SwingNode();
        createAndSetSwingContent(swingNode);

        StackPane pane = new StackPane();
        pane.getChildren().add(swingNode);

        stage.setScene(new Scene(pane, 100, 50));
        stage.show();
    }

    private void createAndSetSwingContent(
        final SwingNode swingNode
    ) {
        SwingUtilities.invokeLater(() -> 
                swingNode.setContent(
                        new JButton("Click me!")
                )
        );
    }

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

依赖和模块管理

如果您正在使用Maven或Gradle来管理JavaFX的依赖项,您可以使用以下代码导入JavaFX/Swing集成库:

<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-swing</artifactId>
    <version>16</version>
</dependency>

如果您正在使用Jigsaw功能编写模块化应用程序,将以下内容放置在您的module-info.java文件中将使JavaFX Swing集成模块对您的应用程序可见:
requires javafx.swing;

在JavaFX中嵌入Swing教程

Oracle提供了一个很好的教程,用于在JavaFX中嵌入Swing内容:

该教程是针对Java 8编写的,但仍然相关。 该教程涵盖了线程管理和事件处理等主题,并建议任何尝试集成JavaFX和Swing的人在尝试集成之前非常了解这些主题,否则可能会发生不良和不可预测的事情。

总的来说,我建议不要混合使用JavaFX和Swing代码,除非这对您的应用程序绝对必要。

Canvas集成和重量级的Swing组件

请注意,从SwingNode文档中可以看到:

包含在JComponent实例中的组件层次结构不应包含任何重量级组件,否则SwingNode可能无法绘制它。

重量级组件的一个示例是Canvas。 如果您希望在JavaFX中使用awt画布,请参见:

具体而言,考虑使用FXGraphics2D库:

FXGraphics2D是Java2D的Graphics2D API的实现,针对JavaFX画布。


Maven不知道javafx.embed.swing。 有任何想法在哪里找到它吗?

这不应该是一个正确配置的Maven设置的情况。

所有JavaFX框架模块都在中央maven仓库中。

标准的Maven安装默认启用了中央Maven仓库。

javafx-swing的Maven协调方式已经在此答案中(位于“依赖项和模块管理”部分)。

请更新依赖版本以匹配您正在使用的JavaFX版本。

该依赖项的最新稳定版本是18.0.1,因此要使用它,请确保您依赖的所有JavaFX组件都使用该版本的JavaFX依赖项。

或者您可以

然而,我建议使用Maven或Gradle构建工具中的依赖项,而不是依赖于手动下载的模块或JavaFX SDK。


整个Maven都不知道javafx.embed.swing在哪里可以找到,有任何想法吗? - F___ThisToxicCommunityHere
更新答案以提供有关查找JavaFX模块的更多信息。 - jewelsea

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接