2
votes

I have a huge swing application and I wanted to embed javafx into it. I tried many times to do that (by following oracle tutorials etc) and I only succeed when I declared a new JFrame to use the JFXPanel component. But, I don't want to use a new Frame, I want to incorporate my Javafx code into the root JFrame of the swing application.

Can we embed javaFX components into JPanel instead of JFrame ? If the answer is yes, why didn't I succeed ?

There is the code sample that is probably wrong :

This class directly extends JPanel and the initialize method is called in an EDT

private void initialize(){

  setLayout(new BorderLayout());

  final JFXPanel fxPanel = new JFXPanel();
  JPanel jp = new JPanel();

  jp.add(fxPanel);
  jp.setVisible(true);
  jp.setSize(500, 300);
  jp.setBackground(Color.CYAN);

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

  add(createButtonsPanel(), BorderLayout.NORTH);
  add(jp,BorderLayout.CENTER);
}


private static void initFX(JFXPanel fxPanel) {
  Scene scene = initScene();
  fxPanel.setScene(scene);
}


private static Scene initScene(){

  Group  root  =  new  Group();
  Scene  scene  =  new  Scene(root, javafx.scene.paint.Color.ALICEBLUE );
  Text  text  =  new  Text();
  text.setX(40);
  text.setY(100);
  text.setFont(new Font(25));
  text.setText("Welcome JavaFX!");
  root.getChildren().add(text);
  return (scene);

}
2
i'm sorry, but what exactly is going wrong?zhujik
In fact, the JavaFX content in my JPanel is hidden. We can only see the swing componentsBaya

2 Answers

2
votes

Took your code, turned it into a SSCCE - everything seems to work, which would indicate the problem is elsewhere in your code. Can you reproduce your problem using this code?

import java.awt.Color;
import java.awt.Container;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.*;
import javafx.scene.text.*;
import javax.swing.*;

public class SwingJFXCombo {

    public static Container initialize(){

        final JFXPanel fxPanel = new JFXPanel();
        JPanel jp = new JPanel();

        jp.add(fxPanel);
        jp.setVisible(true);
        // Really shouldn't do this, so commented it out
        //jp.setPreferredSize(new Dimension(500, 300));
        jp.setBackground(Color.CYAN);

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

        return jp;
    }

    private static void initFX(JFXPanel fxPanel) {
        Scene scene = initScene();
        fxPanel.setScene(scene);
    }

    private static Scene initScene(){
        Group  root  =  new  Group();
        Scene  scene  =  new  Scene(root, javafx.scene.paint.Color.ALICEBLUE );
        Text  text  =  new  Text();
        text.setX(40);
        text.setY(100);
        text.setFont(new Font(25));
        text.setText("Welcome JavaFX!");
        root.getChildren().add(text);
        return (scene);
    }

    public static void main(String[] args){
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        frame.add(SwingJFXCombo.initialize());
        frame.pack();
    }
}
1
votes

Finally, I found a way to make the javafx works. I made my SwingJFXComboclass inherit from an abstract class SimplePullerPanelthat provides methods to handle pulling (SimplePullerPanelextends the abstract class PullerPanelwhich extends JPanel ). To make that work I override the buildContentPanel method in our SwingJFXComboclass

public abstract class SimplePullerPanel extends PullerPanel implements PropertyChangeListener
{
     ...

    protected abstract JComponent buildContentPanel();

    @Override
    protected void buildPanel()
    {

        JComponent oContentPanel = buildContentPanel();
        JPanel panel = new JPanel();
        panel.add(oContentPanel);

        setLayout(new BorderLayout());
        add(panel, BorderLayout.CENTER);
    }

     ...
}

public class SwingJFXCombo extends SimplePullerPanel{

    final JFXPanel fxPanel = new JFXPanel();

    public SwingJFXCombo(){
        setName("fx sample"); 
    }

    private static void initFX(JFXPanel fxPanel) {
        Scene scene = createScene();
        fxPanel.setScene(scene);
    }

    private static Scene createScene(){
        Group  root  =  new  Group();
        Scene  scene  =  new  Scene(root, javafx.scene.paint.Color.ALICEBLUE );

        Text  text  =  new  Text();
        text.setX(40);
        text.setY(100);
        text.setFont(new Font(25));
        text.setText("Welcome JavaFX!");
        root.getChildren().add(text);
        return (scene);
    }

    @Override
    protected JComponent buildContentPanel()
    {
        JPanel frame = new JPanel();
        frame.add(fxPanel);
        frame.setSize(800, 600);
        Platform.runLater(new Runnable() {
            @Override
            public void run()
            {
                initFX(fxPanel);
            }
        });
        return frame;
    }
}

It doesn't explain why the previous code doesn't work and I noticed that if I want to create my custom SimplePullerPanel by deleting some methods that I don't use I face the same problem. Very strange