Basically, I want to "add" a JavaFX video to a Java Swing JFrame, but I also want to draw in that canvas, to do other things while playing the video. I use this code to play the video:
public class ExtVideoPlayer extends Application implements dev.ckitty.kc.utils.interf.MediaPlayer {
@Override
public MediaPlayerType[] getAcceptedTypes() {
return new MediaPlayerType[] { MediaPlayerType.VIDEO };
}
@Override
public void init(File f, String s) {
}
@Override
public void start() {
ExtVideoPlayer.launch(new String[0]);
}
@Override
public void command(String[] args) {
}
@Override
public void stop() {
}
@Override
public void start(Stage primaryStage) throws Exception {
StackPane root = new StackPane();
File video = new File("C:\\Users\\980001005\\Videos\\IMG_6503.mp4");
String url = video.toURI().toURL().toString();
Media media = new Media(url);
MediaPlayer player = new MediaPlayer(media);
MediaView mediaView = new MediaView(player);
root.getChildren().add(mediaView);
Scene scene = new Scene(root, mediaView.getFitWidth(), mediaView.getFitHeight());
primaryStage.setScene(scene);
primaryStage.show();
player.play();
}
}
This works fine, but creates other windows! Of course I could just make it pop-out videos but that would look awful.
I want it to look like Youtube, for example. People would be able to vote for a video and the votes would be shown where Youtube shows recommended videos and adds.
There are some tricks I've seen to put the video inside the JFrame as a Component, but I want it to have a Canvas I can use as well. (So I can draw over the playing video or something)
Please Help!
EDIT! This answer seems like the one I have to use.
EDIT 2
Now I got the canvas and the video in the same JFrame, however, the canvas is not transparent!
The code
public class LayeredDisplay extends Display {
protected JLayeredPane pane;
protected JPanel ontop, behind;
protected JFXPanel jfxPanel;
public LayeredDisplay(String title, int w, int h) {
super(title, w, h, false);
this.createLayers();
this.frame.pack();
this.frame.requestFocus();
this.frame.setSize(w, h);
this.frame.setVisible(true);
}
protected void createLayers() {
this.jfxPanel = new JFXPanel();
this.canvas = new Canvas();
Dimension dim = new Dimension(this.w, this.h);
this.canvas.setPreferredSize(dim);
this.canvas.setMaximumSize(dim);
this.canvas.setMinimumSize(dim);
this.canvas.setFocusable(false);
//this.ontop.add(this.canvas);
//pane.add(this.ontop, 2);
//pane.add(this.behind, 1);
this.frame.add(this.jfxPanel, 0);
this.frame.add(canvas, 1);
}
public JLayeredPane getPane() {
return this.pane;
}
public JPanel getFront() {
return this.ontop;
}
public JPanel getBack() {
return this.behind;
}
public void addComponent(Component comp) {
this.behind.add(comp);
}
public void addVideo(File video1) {
Util.initJavaFX();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
//Code to change Swing data.
File video = new File("C:\\Users\\980001005\\Videos\\IMG_6503.mp4");
String url = null;
try {
url = video.toURI().toURL().toString();
} catch (MalformedURLException e) {
e.printStackTrace();
}
Media media = new Media(url);
MediaPlayer player = new MediaPlayer(media);
MediaView view = new MediaView(player);
player.play();
jfxPanel.setScene(new Scene(new Group(view)));
}
});
}
}
The Display class I'm extending holds the canvas and the JFrame and gives me the Graphics object to draw in the canvas, nothing special.
I got the result I needed! I put the JFXPanel in a class to manage the video. You basically need to add the JFXPanel into a JPanel
public class FramePlayer {
private Display disp;
private JFXPanel jfxPanel;
private int w, h;
public FramePlayer(Display disp, int w, int h, boolean autoInit) {
this.disp = disp;
this.w = w;
this.h = h;
if(autoInit) this.init();
}
public void init() {
this.jfxPanel = new JFXPanel();
Dimension dim = new Dimension(w, h);
this.jfxPanel.setPreferredSize(dim);
this.jfxPanel.setBackground(new Color(0, 0, 0, 255));
this.jfxPanel.setOpaque(false);
this.disp.getFrame().add(this.jfxPanel, 1);
}
public void addVideo(File video1) {
Util.initJavaFX();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// Code to change Swing data.
File video = new File("C:\\Users\\980001005\\Videos\\IMG_6503.mp4");
String url = null;
try {
url = video.toURI().toURL().toString();
} catch (MalformedURLException e) {
e.printStackTrace();
}
Media media = new Media(url);
MediaPlayer player = new MediaPlayer(media);
MediaView view = new MediaView(player);
Group g = new Group(view);
Scene s = new Scene(g);
s.setFill(Paint.valueOf("TRANSPARENT")); // THIS MAKES IT TRANSPARENT!
player.play();
jfxPanel.setScene(s);
}
});
}
public void renderVideo() {
this.jfxPanel.paint(this.disp.getGfx().get());
}
public void renderVideo(KCGraphics gfx) {
this.jfxPanel.paint(gfx.get());
}
}
You need to 1. add the JFXPanel to the JPanel 2. force drawing the JFXPanel into the canvas (well, that's what I had to do..) 3. enjoy!