How to add JFXPanel to already existing swing app
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.
Admin
Updated on June 05, 2022Comments
-
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 almost 8 yearsWhat is the purpose of the
wait
variable? I don't see it being read.