javafx 集成twain,Swing中的JavaFX集成

I'm new to using JavaFX and I'm having some issues figuring out how to integrate an fxml file, in my swing application.

Reading online I've found a way to load the fxml file,and displaying it on screen following this guide:

Integrating JavaFX into Swing Applications

what my code is supposed to do is to load the fxml file, that I've started to design with JavaFX Scene Builder, add the JFXPanel to a JPanel, and return it through a method call. this then gets added to a tabbedPanel in the main application (so there might be multiple distinct JFXPanel open at the same time).

I've kind of figured out some of the problems, but I'm not sure if how to continue. I was able to run one panel, but as in the tutorial I posted, static methods are used, and so I was unable to have multiple distinct panels. I made some changes, but now I'm completely stuck.

This is my current FXML:

And this is my controller class:

package GUI.fcmModeler;

import javafx.application.Platform;

import javafx.embed.swing.JFXPanel;

import javafx.fxml.FXMLLoader;

import javafx.scene.Group;

import javafx.scene.Node;

import javafx.scene.Scene;

import javafx.scene.paint.Color;

import javafx.scene.shape.Circle;

import javax.swing.*;

import java.io.IOException;

import java.util.Random;

public class fcmPanel extends JPanel {

private JPanel frame;

private static Group root=new Group();

private boolean firstRun=true;

Scene scene=null;

private void initAndShowGUI() {

// This method is invoked on the EDT thread

final JFXPanel fxPanel = new JFXPanel();

frame.add(fxPanel);

frame.setSize(1200, 1200);

frame.setVisible(true);

Platform.runLater(new Runnable() {

@Override

public void run() {

initFX(fxPanel);

}

});

frame.add(fxPanel);

frame.setVisible(true);

}

private void initFX(JFXPanel fxPanel) {

// This method is invoked on the JavaFX thread

Scene scene = createScene();

fxPanel.setScene(scene);

}

private Scene createScene() {

//if(firstRun){

//root = new Group();

if(scene==null) {

scene = new Scene(root, Color.ALICEBLUE);

}

try {

Node newLoadedPane = FXMLLoader.load(fcmPanel.class.getResource("/fxml/fcmPanel.fxml"));

root.getChildren().add(newLoadedPane);

} catch (IOException e) {

System.out.print("the file doesn'e exist.\n");

e.printStackTrace();

}

//}

return (scene);

}

public JPanel returnPanel() {

System.out.println("returnpanel");

// if(frame==null){

// frame = new JPanel();

// }

//initFcmPanel();

return frame;

}

public fcmPanel(){

frame = new JPanel();

//root=g;

initFcmPanel();

}

public void initFcmPanel() {

SwingUtilities.invokeLater(new Runnable() {

@Override

public void run() {

initAndShowGUI();

}

});

}

public void addComponent(){

Platform.runLater(new Runnable() {

@Override

public void run() {

System.out.println("added component2");

Circle circle = new Circle(new Random().nextInt(50),Color.BLUE);

root.getChildren().add(circle);

circle.relocate(new Random().nextInt(600),new Random().nextInt(600));

}

});

}

}

The JFXPanel get added to the tabbed panel through this call:

tabbedPanel.addTab(newTabName , null,new fcmPanel().returnPanel(), filePath );

As it is right now, I'm facing the following problem

Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Group@3e0f3500[styleClass=root]is already set as root of another scene

I understand the error message,but I don't know how to solve it.

Thank you in advance.

解决方案

I am not sure what you are trying to achieve. The code posted can not be run as posted, so I created a quick and dirty mcve version of your code which runs with no errors, in hope it will help you see what's wrong or clarify your need :

import java.awt.Dimension;

import java.io.IOException;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JTabbedPane;

import javafx.application.Platform;

import javafx.embed.swing.JFXPanel;

import javafx.fxml.FXMLLoader;

import javafx.scene.Group;

import javafx.scene.Node;

import javafx.scene.Scene;

import javafx.scene.paint.Color;

public class FcmPanel {

private static Group root=new Group();

Scene scene=null;

private void initAndShowGUI() {

// This method is invoked on the EDT thread

final JFXPanel fxPanel = new JFXPanel();

fxPanel.setPreferredSize(new Dimension(600, 400));

JFrame frame = new JFrame();

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Platform.runLater(()-> initFX(fxPanel));

JTabbedPane tabbedPanel = new JTabbedPane();

tabbedPanel.addTab("Just an emty tab", new JPanel() );

tabbedPanel.addTab("FcmPanel", fxPanel );

frame.add(tabbedPanel);

frame.pack();

frame.setVisible(true);

}

private void initFX(JFXPanel fxPanel) {

Scene scene = createScene();

fxPanel.setScene(scene);

}

private Scene createScene() {

if(scene==null) {

scene = new Scene(root, Color.ALICEBLUE);

}

try {

Node newLoadedPane = FXMLLoader.load(getClass().

getResource("FcmPanel.fxml"));

root.getChildren().add(newLoadedPane);

} catch (IOException e) {

e.printStackTrace();

}

return (scene);

}

public static void main(String[] args) {

FcmPanel p = new FcmPanel();

p.initAndShowGUI();

}

}

The fxml is essentially the same. Just changed the Button to a Label which requires no controller :

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值