Adding JavaFX PieChart in JPanel

Tags: , , , ,



I want to add a Pie chart inside a JPanel. I have gone through this and this. But it didnt helped me.

I tried this code in the debugger but it is not getting pass line X. Somehow setScene function is not working and pie chart is not visible in the panel.

Here’s my code:

private void add_pie_chart(JPanel panel)
    {
    JFXPanel dataPanel = new JFXPanel();
    
    PieChart pieChart = new PieChart();

    ObservableList<PieChart.Data> data= FXCollections.observableArrayList(
            new PieChart.Data("test1", 25),
            new PieChart.Data("test 2", 25),
            new PieChart.Data("test 3", 25),
            new PieChart.Data("test 4", 25)
        );
    pieChart.setData(data);
    pieChart.setTitle("test");
    pieChart.setLabelsVisible(true);

    Group root = new Group();

    root.getChildren().add(pieChart);
    
    Scene scene = new Scene(root);
    dataPanel.setScene(scene);   //line X
    //not getting executing

    panel.add(dataPanel, BorderLayout.CENTER);
    panel.setVisible(true);

    }

I am not sure why this is happening. Plz help..

Any help is appreciated. Thanks in advance…

Answer

Both Swing and JavaFX are single-threaded UI toolkits, and each has their own thread for rendering the UI and processing user events. Modifying Swing components and creating Swing windows (e.g. JFrames) must be done on the AWT event dispatch thread. Modifying JavaFX components must be done on the FX Application Thread.

Thus when you’re working with both toolkits together, you have to be careful to delegate the appropriate actions to the appropriate threads. The Javadocs for JFXPanel have more details.

Here’s a complete example which includes a slight re-working of your code and shows how to move the different parts of the code to the appropriate thread:

package org.jamesd.examples.piechartswing;

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;


public class App  {

    public void startUI() {
        JFrame frame = new JFrame();
        JFXPanel fxPanel = new JFXPanel();
        Platform.runLater(() -> createChart(fxPanel));
        
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        panel.add(fxPanel, BorderLayout.CENTER);
        
        frame.add(panel);
        frame.setSize(600,  600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
    
    private void createChart(JFXPanel dataPanel) {
        PieChart pieChart = new PieChart();

        ObservableList<PieChart.Data> data= FXCollections.observableArrayList(
                new PieChart.Data("test1", 25),
                new PieChart.Data("test 2", 25),
                new PieChart.Data("test 3", 25),
                new PieChart.Data("test 4", 25)
            );
        pieChart.setData(data);
        pieChart.setTitle("test");
        pieChart.setLabelsVisible(true);

        Group root = new Group();

        root.getChildren().add(pieChart);
        
        Scene scene = new Scene(root);
        dataPanel.setScene(scene); 
    }

    public static void main(String[] args) {
        App app = new App();
        SwingUtilities.invokeLater(app::startUI);
    }

}

For completenes, module-info.java:

module org.jamesd.examples.piechartswing {
    requires javafx.controls;
    requires java.desktop ;
    requires javafx.swing ;
    exports org.jamesd.examples.piechartswing;
}


Source: stackoverflow