How to add JFXPanel to already existing swing app

10,048

JFXPanel extends javax.swing.JComponent so you will add the JFXPanel to the JFrame just as you would with other Swing components: jFrame.getContentPane().add(myJFXPanel)

SSCCE:

package stack;

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.effect.Reflection;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;

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

public class FXInSwing extends JFrame{

    JFXPanel panel;
    Scene scene;
    StackPane stack;
    Text hello;

    boolean wait = true;

    public FXInSwing(){
        panel = new JFXPanel();
        Platform.runLater(new Runnable(){
            @Override
            public void run() {
                stack = new StackPane();
                scene = new Scene(stack,300,300);
                hello = new Text("Hello");

                scene.setFill(Color.BLACK);
                hello.setFill(Color.WHEAT);
                hello.setEffect(new Reflection());

                panel.setScene(scene);
                stack.getChildren().add(hello);

                wait = false;
            }
        });
        this.getContentPane().add(panel);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(300, 300);
        this.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                new FXInSwing();
            }
        });
    }
}  

Remember when you are working with a JFXPanel, you should initialize it on the Swing Event Dispatching Thread but the setScene() should be done on the JavaFX Application Thread. Else, you will get an exception.

Share:
10,048
Admin
Author by

Admin

Updated on June 05, 2022

Comments

  • Admin
    Admin almost 2 years

    I am very stuck in knowing what to do to integrate my JFXPanel (which is an mp3 player) into an existing Swing app that - which is a JFrame with several different JPanels added to it. I am a complete noob to JavaFX and it is very different from swing.

    I am able to get the code that is below to run and do what I want. It will play mp3 files from a directory that I have them contained in. This is code from a sample that someone wrote. My issue is that this code creates the the JFrame, has the main method and everything just in this code. I have a swing application that is already made that I just want to add a single JFXPanel to that has the functionality as below. There are many new methods in JavaFX that I am very confused with and don't know how to use or where to put in my Swing app. Such as invokeLater runLater and initAndShowGUI. I know this is probably an annoying question and hard to answer from such a noob. I have a project that is due tomorrow night at midnight and I really want to get this implemented as part of the app. We haven't learned JavaFX in class and I didn't know it was going to me this tricky for me.

    package application;  
    
    import java.io.*;  
    import java.util.*;  
    
    import javafx.application.Platform;  
    import javafx.beans.value.*;  
    import javafx.embed.swing.JFXPanel;  
    import javafx.event.*;  
    import javafx.geometry.Pos;  
    import javafx.scene.Scene;  
    import javafx.scene.control.*;  
    import javafx.scene.layout.*;  
    import javafx.scene.media.*;  
    import javafx.util.Duration;  
    
    import javax.swing.*;  
    
    /** Example of playing all mp3 audio files in a given directory  
     * using a JavaFX MediaView launched from Swing  
     */  
    public class JavaFXVideoPlayerLaunchedFromSwing {  
      private static void initAndShowGUI() {  
        // This method is invoked on Swing thread  
        JFrame frame = new JFrame("FX");  
        final JFXPanel fxPanel = new JFXPanel();  
        frame.add(fxPanel);  
        frame.setBounds(200, 100, 800, 250);  
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);  
        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  
        Scene scene = new SceneGenerator().createScene();  
        fxPanel.setScene(scene);  
      }  
    
      public static void main(String[] args) {  
        SwingUtilities.invokeLater(new Runnable() {  
          @Override public void run() {  
            initAndShowGUI();  
          }  
        });  
      }  
    }  
    
    class SceneGenerator {      
      final Label currentlyPlaying = new Label();  
      final ProgressBar progress = new ProgressBar();  
      private ChangeListener<Duration> progressChangeListener;  
    
      public Scene createScene() {  
        final StackPane layout = new StackPane();  
    
        // determine the source directory for the playlist  
        final File dir = new File("C:/Users/Mark/Copy/Mp3Directory");  
        if (!dir.exists() || !dir.isDirectory()) {  
          System.out.println("Cannot find video source directory: " + dir);  
          Platform.exit();  
          return null;  
        }  
    
        // create some media players.  
        final List<MediaPlayer> players = new ArrayList<MediaPlayer>();  
        for (String file : dir.list(new FilenameFilter() {  
          @Override public boolean accept(File dir, String name) {  
            return name.endsWith(".mp3");  
          }  
        })) players.add(createPlayer("file:///" + (dir + "\\" + file).replace("\\", "/").replaceAll(" ", "%20")));  
        if (players.isEmpty()) {  
          System.out.println("No audio found in " + dir);  
          Platform.exit();  
          return null;  
        }      
    
        // create a view to show the mediaplayers.  
        final MediaView mediaView = new MediaView(players.get(0));  
        final Button skip = new Button("Skip");  
        final Button play = new Button("Pause");  
    
        // play each audio file in turn.  
        for (int i = 0; i < players.size(); i++) {  
          final MediaPlayer player     = players.get(i);  
          final MediaPlayer nextPlayer = players.get((i + 1) % players.size());  
          player.setOnEndOfMedia(new Runnable() {  
            @Override public void run() {  
              player.currentTimeProperty().removeListener(progressChangeListener);  
              mediaView.setMediaPlayer(nextPlayer);  
              nextPlayer.play();  
            }  
          });  
        }  
    
        // allow the user to skip a track.  
        skip.setOnAction(new EventHandler<ActionEvent>() {  
          @Override public void handle(ActionEvent actionEvent) {  
            final MediaPlayer curPlayer = mediaView.getMediaPlayer();  
            MediaPlayer nextPlayer = players.get((players.indexOf(curPlayer) + 1) % players.size());  
            mediaView.setMediaPlayer(nextPlayer);  
            curPlayer.currentTimeProperty().removeListener(progressChangeListener);  
            curPlayer.stop();  
            nextPlayer.play();  
          }  
        });  
    
        // allow the user to play or pause a track.  
        play.setOnAction(new EventHandler<ActionEvent>() {  
          @Override public void handle(ActionEvent actionEvent) {  
            if ("Pause".equals(play.getText())) {  
              mediaView.getMediaPlayer().pause();  
              play.setText("Play");  
            } else {  
              mediaView.getMediaPlayer().play();  
              play.setText("Pause");  
            }  
          }  
        });  
    
        // display the name of the currently playing track.  
        mediaView.mediaPlayerProperty().addListener(new ChangeListener<MediaPlayer>() {  
          @Override public void changed(ObservableValue<? extends MediaPlayer> observableValue, MediaPlayer oldPlayer, MediaPlayer newPlayer) {  
            setCurrentlyPlaying(newPlayer);  
          }  
        });  
    
        // start playing the first track.  
        mediaView.setMediaPlayer(players.get(0));  
        mediaView.getMediaPlayer().play();  
        setCurrentlyPlaying(mediaView.getMediaPlayer());  
    
        // silly invisible button used as a template to get the actual preferred size of the Pause button.  
        Button invisiblePause = new Button("Pause");  
        invisiblePause.setVisible(false);  
        play.prefHeightProperty().bind(invisiblePause.heightProperty());  
        play.prefWidthProperty().bind(invisiblePause.widthProperty());  
    
        // layout the scene.  
        layout.setStyle("-fx-background-color: cornsilk; -fx-font-size: 20; -fx-padding: 20; -fx-alignment: center;");  
        layout.getChildren().addAll(  
          invisiblePause,  
          VBoxBuilder.create().spacing(10).alignment(Pos.CENTER).children(  
            currentlyPlaying,  
            mediaView,  
            HBoxBuilder.create().spacing(10).alignment(Pos.CENTER).children(skip, play, progress).build()  
          ).build()  
        );  
        progress.setMaxWidth(Double.MAX_VALUE);  
        HBox.setHgrow(progress, Priority.ALWAYS);  
        return new Scene(layout, 800, 600);  
      }  
    
      /** sets the currently playing label to the label of the new media player and updates the progress monitor. */  
      private void setCurrentlyPlaying(final MediaPlayer newPlayer) {  
        progress.setProgress(0);  
        progressChangeListener = new ChangeListener<Duration>() {  
          @Override public void changed(ObservableValue<? extends Duration> observableValue, Duration oldValue, Duration newValue) {  
            progress.setProgress(1.0 * newPlayer.getCurrentTime().toMillis() / newPlayer.getTotalDuration().toMillis());  
          }  
        };  
        newPlayer.currentTimeProperty().addListener(progressChangeListener);  
    
        String source = newPlayer.getMedia().getSource();  
        source = source.substring(0, source.length() - ".mp4".length());  
        source = source.substring(source.lastIndexOf("/") + 1).replaceAll("%20", " ");  
        currentlyPlaying.setText("Now Playing: " + source);  
      }  
    
      /** @return a MediaPlayer for the given source which will report any errors it encounters */  
      private MediaPlayer createPlayer(String aMediaSrc) {  
        System.out.println("Creating player for: " + aMediaSrc);  
        final MediaPlayer player = new MediaPlayer(new Media(aMediaSrc));  
        player.setOnError(new Runnable() {  
          @Override public void run() {  
            System.out.println("Media error occurred: " + player.getError());  
          }  
        });  
        return player;  
      }  
    }  
    
  • nafg
    nafg almost 8 years
    What is the purpose of the wait variable? I don't see it being read.