So I've recently started working with JavaFX to try and insert video and audio into my java programs. Audio has worked just fine, but for some reason every time I try and play a video file, it returns a MEDIA_UNSUPPORTED exception. I've read around and saw that the video file needed to be MP4 (which it is), so I tried converting it to a different type then re-converting it to MP4 (H.264 & AAC) with a few different converters and nothing changes.
Here's the code I'm working with:
import java.net.URL;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.embed.swing.JFXPanel;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.util.Duration;
public class CallVideo extends JFrame{
public static final String VID_URL = "file:/C:/Users/Public/Videos/Videos/testCon.mp4"; //http://static.clipcanvas.com/sample/clipcanvas_14348_H264_320x180.mp4
private JFXPanel panel;
public CallVideo(String url)
{
panel = new JFXPanel();
Platform.runLater(new Runnable()
{
public void run()
{
final Media clip = new Media(VID_URL);
final MediaPlayer player = new MediaPlayer(clip);
final MediaView viewer = new MediaView(player);
viewer.setFitHeight(200);
viewer.setFitWidth(200);
final Button button = new Button("Bing Zzzzt!");
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event)
{
viewer.getMediaPlayer().seek(Duration.ZERO);
viewer.getMediaPlayer().play();
}
});
setMediaEventHandlers(viewer);
VBox vid = new VBox();
vid.getChildren().addAll(viewer, button);
Scene aScene = new Scene(vid, 200, 200);
panel.setScene(aScene);
}
});
this.add(panel);
this.setSize(500, 500);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
private void setMediaEventHandlers(final MediaView view) {
final MediaPlayer player = view.getMediaPlayer();
System.out.println("Initial: " + player.getStatus());
player.statusProperty().addListener(new ChangeListener<MediaPlayer.Status>() {
#Override
public void changed(ObservableValue<? extends MediaPlayer.Status> observable, MediaPlayer.Status oldStatus, MediaPlayer.Status curStatus) {
System.out.println("Current: " + curStatus);
}
});
if (player.getError() != null) {
System.out.println("Initial Error: " + player.getError());
}
player.setOnError(new Runnable() {
#Override public void run() {
System.out.println("Current Error: " + player.getError());
}
});
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new CallVideo(VID_URL);
}
});
}
}
The error occurs on the line where the "Media" object is initialized (beginning of constructor).
I'm at a total loss to see what the problem is. I've seen questions about the audio playing but the video not showing up, but it doesn't even do that for me...
In case someone needs it:
Eclipse
JDK 7
JavaFX 2.0
Windows 7 Pro
EDIT:
First off, I noticed I'm actually using JavaFX 2.0... Might that be the problem?
I've tested both versions provided in the answer, and both return this error (called by the statusListener) when using the URL provided by that answer:
Current Error: MediaException: MEDIA_UNSUPPORTED : com.sun.media.jfxmedia.MediaException: "Error enter code herelocator unsupported media format" : com.sun.media.jfxmedia.MediaException: "Error locator unsupported media format"
When using my own file, the program returns this error immediately upon calling the Media constructor, as before:
Exception in thread "AWT-EventQueue-0" MediaException: MEDIA_UNSUPPORTED : Unrecognized file signature!
at javafx.scene.media.Media.<init>(Media.java:382)
at CallVideo.<init>(CallVideo.java:27)
at CallVideo$5.run(CallVideo.java:90)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
I've updated the code I'm using above.
SOLVED!
The reason is really I was using an inappropriate JavaFX (and possibly JDK) for the job. I'm not really in control of that stuff since these are school computers, but that messed me up something good... Thanks for the help! I updated it with my final code.
This worked for me after I modified your program a little bit to fix a couple of issues.
Some changes I applied:
A MediaView is necessary to view the video, so one needs to be created and added to an active JavaFX scene in order for the video to be seen.
Some JavaFX controls need to be created on the JavaFX application thread rather than the main thread, otherwise you get java.lang.IllegalStateException: Toolkit not initialized.
Monitoring media error events and adding some diagnostic logs helps troubleshoot media encoding issues.
A JavaFX only solution
Your program embeds JavaFX in a Swing application which is a bit more complex then just playing Media in a standard JavaFX application. Corresponding code for playback of an mp4 in a standard JavaFX application is supplied in my answer to: Can't play mp4 converted file - JavaFX 2.1. Using just JavaFX is recommended unless you have a specific need for Swing (such as embedding your JavaFX based media player inside an existing large Swing application).
Oracle provide a good tutorial for Incorporating Media Assets Into JavaFX Applications.
The JavaFX media package description documents the media playback encodings, containers and protocols which JavaFX supports.
Sample for playing back mp4 video from a Swing App using a JavaFX MediaPlayer
Note the sample only catches a subset of the possible media errors. For a code template which can catch and log all media errors see the JavaFX media error handling documentation.
import javax.swing.*;
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.VBox;
import javafx.scene.media.*;
import javafx.util.Duration;
public class VideoPlayer extends JFrame {
public static final String VID_URL =
"http://static.clipcanvas.com/sample/clipcanvas_14348_H264_320x180.mp4";
private static final int VID_WIDTH = 320;
private static final int VID_HEIGHT = 180;
private static final int PLAYER_WIDTH = 320;
private static final int PLAYER_HEIGHT = 265;
private void play(final String url) {
final JFXPanel panel = new JFXPanel();
Platform.runLater(new Runnable() {
#Override public void run() {
initFX(panel, url);
}
});
this.add(panel);
this.setSize(PLAYER_WIDTH, PLAYER_HEIGHT);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
private void initFX(JFXPanel panel, String url) {
MediaView mediaView = createMediaView(url);
final Scene playerScene = new Scene(
createPlayerLayout(mediaView),
PLAYER_WIDTH,
PLAYER_HEIGHT
);
setMediaEventHandlers(
mediaView
);
panel.setScene(playerScene);
}
private MediaView createMediaView(String url) {
final Media clip = new Media(url);
final MediaPlayer player = new MediaPlayer(clip);
final MediaView view = new MediaView(player);
view.setFitWidth(VID_WIDTH);
view.setFitHeight(VID_HEIGHT);
return view;
}
private VBox createPlayerLayout(final MediaView view) {
final Button button = new Button("Play From Start");
button.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent event) {
view.getMediaPlayer().seek(Duration.ZERO);
view.getMediaPlayer().play();
}
});
final VBox layout = new VBox(8);
layout.setAlignment(Pos.CENTER);
layout.getChildren().addAll(
view,
button
);
layout.setStyle("-fx-background-color: linear-gradient(to bottom, derive(lightseagreen, -20%), lightseagreen);");
return layout;
}
private void setMediaEventHandlers(final MediaView view) {
final MediaPlayer player = view.getMediaPlayer();
System.out.println("Initial: " + player.getStatus());
player.statusProperty().addListener(new ChangeListener<MediaPlayer.Status>() {
#Override
public void changed(ObservableValue<? extends MediaPlayer.Status> observable, MediaPlayer.Status oldStatus, MediaPlayer.Status curStatus) {
System.out.println("Current: " + curStatus);
}
});
if (player.getError() != null) {
System.out.println("Initial Error: " + player.getError());
}
player.setOnError(new Runnable() {
#Override public void run() {
System.out.println("Current Error: " + player.getError());
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override public void run() {
VideoPlayer player = new VideoPlayer();
player.play(VID_URL);
}
});
}
}
SOLVED!
Nice to see that original poster was able to get video playback working and the final error was just using an old JavaFX version (2.0) which does not support mp4 playback. Updating to JavaFX 2.2+ (which does support mp4 playback) fixed the issue.
Related
my apologies if this is an easy thing for you, but my mind boggles. After several years of not programming at all, I am working on a pet project (2d tile based game engine) where I would like to use Java FX headless in order to make use of the graphics capabilities.
I have understood from here and here
that you need to a Java FX Application in order to have the graphics system initialized.
So I basically took the ImageViewer example and implemented Runnable:
package net.ck.game.test;
import java.io.BufferedReader;
import java.util.ArrayList;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Logger;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class ImageTest extends Application implements Runnable {
protected static final Logger logger = (Logger) LogManager.getLogger(ImageTest.class);
BufferedReader x;
#Override public void start(#SuppressWarnings("exports") Stage stage) {
logger.error(Thread.currentThread().getName() + ", executing run() method!");
Image standardImage = new Image("file:graphics/image1.png");
logger.error("image height image1: "+ standardImage.getHeight());
logger.error("image width image1:" + standardImage.getWidth());
Image movingImage = new Image("file:graphics/image2.png");
ArrayList<Image> images = new ArrayList<Image>();
images.add(movingImage);
images.add(standardImage);
ImageView iv1 = new ImageView();
iv1.setImage(standardImage);
ImageView iv2 = new ImageView();
iv2.setImage(movingImage);
Group root = new Group();
Scene scene = new Scene(root);
scene.setFill(Color.BLACK);
HBox box = new HBox();
box.getChildren().add(iv1);
box.getChildren().add(iv2);
root.getChildren().add(box);
stage.setTitle("ImageView");
stage.setWidth(415);
stage.setHeight(200);
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void run()
{
Application.launch(ImageTest.class);
}
}
When I run this as its own application, this works fine and displays the two images I want it to display.
When I run it like this in the "game" constructor:
public class Game {
private boolean animated;
public boolean isAnimated() {
return animated;
}
public void setAnimated(boolean animated) {
this.animated = animated;
}
public Game() {
setAnimated(true);
if (isAnimated() == true)
{
ImageTest imageTest = new ImageTest();
new Thread(imageTest).start();
}
}
There are no errors, ImageTest runs in its own thread, the application window opens, but it is empty.
I do not understand this at all, why is that?
Can someone pleaese shed some light on this?
UPDATE:
I had different working contexts by accident. Fixing this fixed the problem.
UPDATE: I had different working contexts by accident. Fixing this fixed the problem.
So I'm using VLCJ and the VLC player for java to play a video when I run my program. Problem is, the video player only closes when the user clicks the "x" button. Is there a way to close it automatically when the video ends?
Thanks!
If it helps, here's my code:
//////Main class:
package switchAndAnim;
import java.io.File;
import javax.swing.JFileChooser;
public class Start {
public static void main(String[] args)
{
//location of vlc files, media file
new MediaPlayer("vlc-2.0.2", "ryankilp2.wmv").run();
}
}
///////MediaPlayer class:
package switchAndAnim;
import javax.swing.JFrame;
import com.sun.jna.NativeLibrary;
import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;
public class MediaPlayer {
private JFrame ourFrame = new JFrame();
private EmbeddedMediaPlayerComponent ourMediaPlayer;
private String mediaPath = "";
MediaPlayer(String vlcPath,String mediaURL)
{
this.mediaPath = mediaURL;
NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), vlcPath);
ourMediaPlayer = new EmbeddedMediaPlayerComponent();
ourFrame.setContentPane(ourMediaPlayer);
ourFrame.setSize(640,480);
ourFrame.setVisible(true);
ourFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void run()
{
ourMediaPlayer.getMediaPlayer().playMedia(mediaPath);
}
}
The media player has all sorts of events you can listen for, one of them being the "finished" event that fires when the end of the video is reached.
ourMediaPlayer = new EmbeddedMediaPlayerComponent() {
public void finished(MediaPlayer mediaPlayer) {
ourMediaPlayer.release(); // In practice, this line is optional
System.exit(0);
}
}
I used System.exit() since your question set EXIT_ON_CLOSE, but equally you could hide or dispose the frame instead depending on your use case.
I followed some tutorials about combining JavaFX with Swing (JFrame) to play a video, however all I get is a black screen where the video is supposed to be without any actual content playing, No errors are reported either.
What am I doing wrong here and why wont the video play?
I tried several .flv videos, none of them will start playing (they do play when I open them in my browser)
I'm running jre7 and jdk1.7.0_45 on windows 8.1 N Pro with the K-lite full codec pack installed
EDIT: updated my code after the comment of jewelsea, nothing has changed, the black box still appears without content playing, the console doesn't show any text coming up
package com.example.test;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.SceneBuilder;
import javafx.scene.media.Media;
import javafx.scene.media.MediaErrorEvent;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.paint.Color;
import javax.swing.*;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
initAndShowGUI();
}
});
}
private static void initAndShowGUI() {
// This method is invoked on the EDT thread
JFrame frame = new JFrame("Test");
final JFXPanel fxPanel = new JFXPanel();
frame.add(fxPanel);
frame.setSize(640, 480);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Platform.runLater(new Runnable() {
#Override
public void run() {
initFX(fxPanel);
}
});
}
private static void initFX(JFXPanel fxPanel) {
// This method is invoked on the JavaFX thread
Scene scene = createScene();
fxPanel.setScene(scene);
}
private static Scene createScene() {
String source;
Media media;
MediaPlayer mediaPlayer;
MediaView mediaView = null;
try {
media = new Media("http://download.oracle.com/otndocs/products/javafx/oow2010-2.flv");
if (media.getError() == null) {
media.setOnError(new Runnable() {
public void run() {
// Handle asynchronous error in Media object.
System.out.println("Handle asynchronous error in Media object");
}
});
try {
mediaPlayer = new MediaPlayer(media);
mediaPlayer.setAutoPlay(true);
if (mediaPlayer.getError() == null) {
mediaPlayer.setOnError(new Runnable() {
public void run() {
// Handle asynchronous error in MediaPlayer object.
System.out.println("Handle asynchronous error in MediaPlayer object");
}
});
mediaView = new MediaView(mediaPlayer);
mediaView.setOnError(new EventHandler() {
public void handle(MediaErrorEvent t) {
// Handle asynchronous error in MediaView.
System.out.println("Handle asynchronous error in MediaView: "+ t.getMediaError());
}
#Override
public void handle(Event arg0) {
// TODO Auto-generated method stub
System.out.println("Handle asynchronous error in MediaView arg0: "+arg0.toString());
}
});
} else {
// Handle synchronous error creating MediaPlayer.
System.out.println("Handle synchronous error creating MediaPlayer");
}
} catch (Exception mediaPlayerException) {
// Handle exception in MediaPlayer constructor.
System.out.println("Handle exception in MediaPlayer constructor: "+ mediaPlayerException.getMessage());
}
} else {
// Handle synchronous error creating Media.
System.out.println("Handle synchronous error creating Media");
}
} catch (Exception mediaException) {
// Handle exception in Media constructor.
System.out.println("Handle exception in Media constructor: "+mediaException.getMessage());
}
Group root = new Group();
Scene scene = SceneBuilder.create().width(640).height(480).root(root).fill(Color.WHITE).build();
if(mediaView != null) {
root.getChildren().add(mediaView);
}
return scene;
}
}
So I installed the windows media feature pack in order to get adobe premiere pro working (because it required a dll file from windows media player (which I didn't had installed because I run an N version of windows) and now the video does play for me.
I can't say with 100% confirmation the cause was not having WMP installed as the media feature pack might as well have installed something else that solved my problem, nonetheless, problem solved :)
I want to thank the other answers for trying, I really appreciate it.
Please do not mind if i am writing this answer. I know this is a very old question but this answer might help others. I am currently developing a JavaFX application which needs to execute a file depending upon its type.
My application played the video for the first time but when i clicked on another mp4 video file it didn't play.
Here is my initial code.
private void playVideo(String fileLocation) {
System.out.println("VideoProcesser Thread = " + Thread.currentThread().getName());
media = new Media(new File(fileLocation).toURI().toString());
mediaPlayer = new MediaPlayer(media);
mediaView = new MediaView(mediaPlayer);
runnable = () -> {
System.out.println("Inside runnable VideoProcesser Thread = " + Thread.currentThread().getName());
mediaPlayer.play();
};
mediaPlayer.setOnReady(runnable);
setVideoMediaStatus(PLAYING);
pane.getChildren().add(mediaView);
}
Then since the video player screen was dark, i thought the problem was with media view, so i added the following two line,
if(mediaView == null) {
mediaView = new MediaView(mediaPlayer);
}
mediaView.setMediaPlayer(mediaPlayer);
Now, when i click on different videos my application just plays fine.
Here is the complete code.
Media media;
MediaPlayer mediaPlayer;
MediaView mediaView;
private void playVideo(String fileLocation) {
System.out.println("VideoProcesser Thread = " + Thread.currentThread().getName());
media = new Media(new File(fileLocation).toURI().toString());
mediaPlayer = new MediaPlayer(media);
mediaPlayer.setAutoPlay(true);
if(mediaView == null) {
mediaView = new MediaView(mediaPlayer);
}
mediaView.setMediaPlayer(mediaPlayer);
mediaPlayer.play();
mediaPlayer.setOnError(() -> System.out.println("Current error: "+mediaPlayer.getError()));
setVideoMediaStatus(PLAYING);
pane.getChildren().add(mediaView);
}
Note that if you are using FXML to instantiate mediaView, then do not instantiate it again. Instantiating it again might make mediaView loose the reference of original node.
Refer to this post and answer by itachi,
javafx mediaview only the audio is playing
try this, it works for me:
package de.professional_webworkx.swing;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.SceneBuilder;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javax.swing.JFrame;
public class MyFrame extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* Create a new Frame, set title, ...
*/
public MyFrame() {
this.setTitle("Swing and JavaFX");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(1024, 768);
// create a JFXPanel
final JFXPanel jfxPanel = new JFXPanel();
// add the jfxPanel to the contentPane of the JFrame
this.getContentPane().add(jfxPanel);
this.setVisible(true);
Platform.runLater(new Runnable() {
#Override
public void run() {
jfxPanel.setScene(initScene());
}
});
}
public static final void main (String[] args) {
new MyFrame();
}
/**
* init the JFX Scene and
* #return scene
*/
private Scene initScene() {
Group root = new Group();
SceneBuilder<?> sb = SceneBuilder.create().width(640).height(400).root(root);
Media video = new Media("http://download.oracle.com/otndocs/products/javafx/oow2010-2.flv");
MediaPlayer mediaPlayer = new MediaPlayer(video);
mediaPlayer.setAutoPlay(true);
mediaPlayer.play();
MediaView view = new MediaView(mediaPlayer);
root.getChildren().add(view);
Scene scene = sb.build();
return scene;
}
}
Patrick
I took your code and tried running it on my machine (Win7 JDK 1.7.0_25) and got the same results. Black box and no video.
I noticed you aren't setting mediaPlayer.setAutoPlay(true) so I added that call to the createScene() right before mediaPlayer is passed to MediaView. Now the playback seems to work for me.
// ... prior code omitted
// added this to OP's code
mediaPlayer.setAutoPlay(true);
mediaView = new MediaView(mediaPlayer);
mediaView.setOnError(new EventHandler() {
public void handle(MediaErrorEvent t) {
// Handle asynchronous error in MediaView.
System.out.println("Handle asynchronous error in MediaView: "+ t.getMediaError());
}
// ... additional code omitted
Edit: The autoPlay property defaults to false - you can call mediaPlayer.isAutoPlay() to check this. Without either calling mediaPlayer.setAutoPlay(true) or mediaPlayer.play() the video will never start playing.
Edit 2: I just noticed in the comments on another answer that you are having trouble playing the video outside of JavaFX. If you don't already have it installed, try downloading VLC to see if the video can play using that. I believe installing ffdshow tryouts will provide the necessary codecs to play FLV in Windows Media Player. (Although I thought all versions of K-lite codec pack included FLV support)
I need to be able to play Audio files (MP3 / Wav) in a normal Java project. I'd prefer using the new JavaFX MediaPlayer rather than JMF. I wrote some code to test this:
public void play()
{
URL thing = getClass().getResource("mysound.wav");
Media audioFile = new Media( thing.toString() );
try
{
MediaPlayer player = new MediaPlayer(audioFile);
player.play();
}
catch (Exception e)
{
System.out.println( e.getMessage() );
System.exit(0);
}
}
When I run this, I get the exception: Toolkit not initialized
I get that this has something to do with the JavaFX thread. My question is, how can I solve this? Do I need to create a JavaFX Panel just to play some audio files in the background of my normal app, or is there any other way?
Edit: Stacktrace:
java.lang.IllegalStateException: Toolkit not initialized
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:121)
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:116)
at javafx.application.Platform.runLater(Platform.java:52)
at javafx.scene.media.MediaPlayer.init(MediaPlayer.java:445)
at javafx.scene.media.MediaPlayer.<init>(MediaPlayer.java:360)
at javaapplication6.JavaApplication6.play(JavaApplication6.java:23)
at javaapplication6.JavaApplication6.main(JavaApplication6.java:14)
For a solution with integrates a JavaFX MediaPlayer in Swing
Use a JFXPanel and be careful to only use JavaFX objects on the JavaFX thread and after the JavaFX system has been properly initialized.
JavaFX is normal Java which makes the question a bit confusing, but I guess you mean Swing.
Here's a sample audio player which is launched from Swing. The sample assumes that there are a bunch of mp3 files in the default public sample music folder for Windows 7 (C:\Users\Public\Music\Sample Music) and plays each file in turn.
JavaFXMediaPlayerLaunchedFromSwing.java
This code is responsible for creating a Swing application which, in turn, initializes the JavaFX toolkit and creates a JavaFX scene on the JavaFX application thread.
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javax.swing.*;
/**
* Example of playing all mp3 audio files in a given directory
* using a JavaFX MediaView launched from Swing
*/
public class JavaFXMediaPlayerLaunchedFromSwing {
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(() -> initFX(fxPanel));
}
private static void initFX(JFXPanel fxPanel) {
// This method is invoked on JavaFX thread
Scene scene = new MediaSceneGenerator().createScene();
fxPanel.setScene(scene);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(
JavaFXMediaPlayerLaunchedFromSwing::initAndShowGUI
);
}
}
MediaSceneGenerator.java
Creates a JavaFX media player which sequentially plays all of the .mp3 media files in a given folder. It provides some controls for the media (play, pause, skip track, current track play progress indicator).
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.layout.VBox;
import javafx.scene.media.*;
import javafx.util.Duration;
import java.io.File;
import java.util.*;
public class MediaSceneGenerator {
private static final String MUSIC_FOLDER = "C:\\Users\\Public\\Music\\Sample Music";
private static final String MUSIC_FILE_EXTENSION = ".mp3";
private final Label currentlyPlaying = new Label();
private 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(MUSIC_FOLDER);
if (!dir.exists() || !dir.isDirectory()) {
System.out.println("Cannot find media source directory: " + dir);
Platform.exit();
return null;
}
// create some media players.
final List<MediaPlayer> players = new ArrayList<>();
for (String file : Objects.requireNonNull(dir.list((dir1, name) -> name.endsWith(MUSIC_FILE_EXTENSION))))
players.add(
createPlayer(
normalizeFileURL(dir, file)
)
);
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++) {
MediaPlayer player = players.get(i);
MediaPlayer nextPlayer = players.get((i + 1) % players.size());
player.setOnEndOfMedia(() -> {
final MediaPlayer curPlayer = mediaView.getMediaPlayer();
nextPlayer.seek(Duration.ZERO);
if (nextPlayer != curPlayer) {
curPlayer.currentTimeProperty().removeListener(progressChangeListener);
}
mediaView.setMediaPlayer(nextPlayer);
nextPlayer.play();
});
}
// allow the user to skip a track.
skip.setOnAction(actionEvent -> {
final MediaPlayer curPlayer = mediaView.getMediaPlayer();
MediaPlayer nextPlayer = players.get((players.indexOf(curPlayer) + 1) % players.size());
nextPlayer.seek(Duration.ZERO);
mediaView.setMediaPlayer(nextPlayer);
if (nextPlayer != curPlayer) {
curPlayer.currentTimeProperty().removeListener(progressChangeListener);
}
nextPlayer.play();
});
// allow the user to play or pause a track.
play.setOnAction(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(
(observableValue, oldPlayer, 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.
HBox controls = new HBox(10, skip, play, progress);
controls.setAlignment(Pos.CENTER);
VBox mediaPanel = new VBox(10, currentlyPlaying, mediaView, controls);
layout.setStyle("-fx-background-color: cornsilk; -fx-font-size: 20; -fx-padding: 20; -fx-alignment: center;");
layout.getChildren().addAll(
invisiblePause,
mediaPanel
);
progress.setMaxWidth(Double.MAX_VALUE);
HBox.setHgrow(progress, Priority.ALWAYS);
return new Scene(layout);
}
/**
* 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 = (observableValue, oldValue, newValue) ->
progress.setProgress(
1.0 * newPlayer.getCurrentTime().toMillis() / newPlayer.getTotalDuration().toMillis()
);
newPlayer.currentTimeProperty().addListener(progressChangeListener);
String source = getUserFriendlyMediaName(newPlayer);
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(() -> System.out.println("Media error occurred: " + player.getError()));
return player;
}
private String normalizeFileURL(File dir, String file) {
return "file:///" + (dir + "\\" + file).replace("\\", "/").replaceAll(" ", "%20");
}
private String getUserFriendlyMediaName(MediaPlayer newPlayer) {
String source = newPlayer.getMedia().getSource();
source = source.substring(0, source.length() - MUSIC_FILE_EXTENSION.length());
source = source.substring(source.lastIndexOf("/") + 1).replaceAll("%20", " ");
return source;
}
}
If you just want a native JavaFX application with a MediaPlayer and no Swing
The solution above which uses Swing answers the question asked. However, I have noted that sometimes people have picked up this answer and used it to create Java based media players even when they don't have an existing Swing application that they are embedding their application into.
If you don't have an existing Swing application, then eliminate the Swing code completely from your application and write a native JavaFX application instead. To do this, use the JavaFXMediaPlayer class below instead of the class JavaFXMediaPlayerLaunchedFromSwing from the sample above.
JavaFXMediaPlayer
import javafx.application.Application;
import javafx.stage.Stage;
public class JavaFXMediaPlayer extends Application {
#Override
public void start(Stage stage) throws Exception {
stage.setScene(new MediaSceneGenerator().createScene());
stage.show();
}
}
Answers to follow-up questions
Will my .JAR file built via swing automatically have JavaFX added to it once I add it to the libraries in netbeans?
Note: info in this follow-up answer on packaging is likely dated now and other preferred packaging options exist at this time (e.g https://github.com/openjfx/javafx-maven-plugin).
Technically, Swing doesn't build Jar files but the jar of javafx packaging commands do.
If your app contains JavaFX, then, it's best to use the JavaFX packaging tools. Without them, you may have some deployment issues issues as the Java runtime jar (jfxrt.jar) is not automatically on the java boot classpath for jdk7u7. Users can manually add it to their runtime classpath, but it could be a bit of a pain. In future jdk versions (perhaps jdk7u10 or jdk8), jfxrt.jar will be on the classpath. Even then, use of the JavaFX packaging tools would still be recommended as it will be the best way to ensure that your deployment package will work in the most compatible way.
The SwingInterop NetBeans project is a sample NetBeans project which utilizes JavaFX deployment tools for a Swing project embedding JavaFX components. Source for SwingInterop is part of the JDK 7 and JavaFX Demos and Samples download.
Is there a way of opening a full web page using Java, I have to check the time taken in opening full web page in a Java user end application, I have tried this code:
URL ur = new URL("http://www.google.com/");
HttpURLConnection yc =(HttpURLConnection) ur.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
but this gives me the source code of the url... that's useless for me!
as I need to record the time taken by a webpage to load on my desktop by making a Java application.
Everything is on client site!
Here is a JavaFX based sample:
import java.util.Date;
import javafx.application.Application;
import javafx.beans.value.*;
import javafx.concurrent.Worker.State;
import javafx.event.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.layout.*;
import javafx.scene.web.WebEngine;
import javafx.stage.Stage;
/** times the loading of a page in a WebEngine */
public class PageLoadTiming extends Application {
public static void main(String[] args) { launch(args); }
#Override public void start(Stage stage) {
final Label instructions = new Label(
"Loads a web page into a JavaFX WebEngine. " +
"The first page loaded will take a bit longer than subsequent page loads due to WebEngine intialization.\n" +
"Once a given url has been loaded, subsequent loads of the same url will be quick as url resources have been cached on the client."
);
instructions.setWrapText(true);
instructions.setStyle("-fx-font-size: 14px");
// configure some controls.
final WebEngine engine = new WebEngine();
final TextField location = new TextField("http://docs.oracle.com/javafx/2/get_started/jfxpub-get_started.htm");
final Button go = new Button("Go");
final Date start = new Date();
go.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent arg0) {
engine.load(location.getText());
start.setTime(new Date().getTime());
}
});
go.setDefaultButton(true);
final Label timeTaken = new Label();
// configure help tooltips.
go.setTooltip(new Tooltip("Start timing the load of a page at the entered location."));
location.setTooltip(new Tooltip("Enter the location whose page loading is to be timed."));
timeTaken.setTooltip(new Tooltip("Current loading state and time taken to load the last page."));
// monitor the page load status and update the time taken appropriately.
engine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
#Override public void changed(ObservableValue<? extends State> state, State oldState, State newState) {
switch (newState) {
case SUCCEEDED: timeTaken.setText(((new Date().getTime()) - start.getTime()) + "ms"); break;
default: timeTaken.setText(newState.toString());
}
}
});
// layout the controls.
HBox controls = HBoxBuilder.create().spacing(10).children(new Label("Location"), location, go, timeTaken).build();
HBox.setHgrow(location, Priority.ALWAYS);
timeTaken.setMinWidth(120);
// layout the scene.
VBox layout = new VBox(10);
layout.setStyle("-fx-padding: 10; -fx-background-color: cornsilk; -fx-font-size: 20px;");
layout.getChildren().addAll(controls, instructions);
stage.setTitle("Page load timing");
stage.getIcons().add(new Image("http://icons.iconarchive.com/icons/aha-soft/perfect-time/48/Hourglass-icon.png"));
stage.setScene(new Scene(layout, 1000, 110));
stage.show();
// trigger loading the default page.
go.fire();
}
}
Yeah home is right that should do the trick. But this way is much more simpler... Although a bit erroneous it should serve fine for benchmark purposes.
JEditorPane editorPane = new JEditorPane();
editorPane.setPage(new URL("http://www.google.com"));
The scripts are still rendered on the screen if you just use this snippet, although it can be worked around I don't think you will need to bother with that since you need to just benchmark loading time... However the results may be varying very slightly since it doesn't take time to run the JavaScript.
You can use Cobra
You can use plain Swing also
You can also use JavaFX to do it like this:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.web.WebView;
public class MyWebView extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(final Stage primaryStage) {
final WebView wv = new WebView();
wv.getEngine().load("http://www.google.com");
primaryStage.setScene(new Scene(wv));
primaryStage.show();
}
}
To open a web page using java , try the following code :
import java.io.*;
public class b {
public static void main(String args[])throws IOException
{
String downloadURL="<url>";
java.awt.Desktop myNewBrowserDesktop = java.awt.Desktop.getDesktop();
try
{
java.net.URI myNewLocation = new java.net.URI(downloadURL);
myNewBrowserDesktop.browse(myNewLocation);
}
catch(Exception e)
{
}
}
}
This will open the web page in your default browser . As for the time taken to load part , have a look here . There are a lot of suggestions there .