0

I am writing a piece of educational software, and want the user to be able to select a video to watch from a list that lies within my JavaFX GUI. I have created a mediaPlayer class that contains a main method that runs the code and displays the video correctly, however my next task is to instantiate the mediaPlayer class, and pass the URL of the video to be watched as a parameter.

I have attempted to code a MediaPlayerTest, whereby I instantiate the mediaPlayer, pass it a URL as a parameter, and then call the start() method, however I am getting the following errors when running my tester class:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at javafx.scene.web.WebView.<init>(WebView.java:271)
    at Media.mediaPlayer.start(mediaPlayer.java:34)
    at Media.MediaPlayerTest.main(MediaPlayerTest.java:23)
Caused by: java.lang.RuntimeException: Internal graphics not initialized yet
    at com.sun.glass.ui.Screen.getScreens(Screen.java:70)
    at com.sun.javafx.webkit.prism.PrismGraphicsManager.<init>(PrismGraphicsManager.java:43)
    at javafx.scene.web.WebEngine.<clinit>(WebEngine.java:290)
    ... 3 more

You can find the tester class and mediaPlayer class code below:

public class mediaPlayer extends Application {   

    // The url of the video to be played
    String url = "https://www.youtube.com/embed/CySfQY_lgr4";

    public mediaPlayer(String url) {
        this.url = url;
    }

    @Override 
    public void start(Stage stage) throws Exception {
        WebView webview = new WebView();
        webview.getEngine().load(url);

        webview.setPrefSize(640, 390);
        stage.setScene(new Scene(webview));
        stage.show();
    }

    public static void main(String[] args) { 
        launch(args);
    }

}

And MediaPlayerTest class:

public class MediaPlayerTest {

    public static void main (String[] args) {
        try {
            mediaPlayer mp = new mediaPlayer("https://www.youtube.com/embed/CySfQY_lgr4");
            mp.start(null);
        } catch (Exception ex) {
            Logger.getLogger(MediaPlayerTest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}

Any help for solving this issue would be much appreciated.

dzikoysk
  • 1,560
  • 1
  • 15
  • 27
freshwaterjoe
  • 101
  • 3
  • 16

1 Answers1

0

You should not invoke start() yourself: it is invoked as part of a complex process when you call launch().

So you can do:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

import java.util.List ;

public class MediaPlayer extends Application {   



  public static void main(String[] args) { launch(args); }


  // The url of the video to be played
  private String url = "https://www.youtube.com/embed/CySfQY_lgr4";


  @Override public void start(Stage stage) throws Exception {

    List<String> params = getParameters.getRaw();
    if (params.size() > 0) {
        url = params.get(0);
    }

    WebView webview = new WebView();
    webview.getEngine().load(url);
    webview.setPrefSize(640, 390);

    stage.setScene(new Scene(webview));
    stage.show();
  }    
}

and then (if you want, but typically this is not a good approach):

import java.util.logging.Level;
import java.util.logging.Logger;


/**
 *
 * @author Joe
 */
public class MediaPlayerTest {

    public static void main (String[] args) {

        try {
            Application.launch(MediaPlayer.class, "https://www.youtube.com/embed/CySfQY_lgr4");
        } catch (Exception ex) {
            Logger.getLogger(MediaPlayerTest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}

Obviously here the MediaPlayerTest class is somewhat redundant anyway: you can just run the MediaPlayer class directly.

The bottom line is that Application subclasses represent the entry point of the application, and as such they are not designed to be reusable. If you want to reuse your MediaPlayer class elsewhere, then refactor it so it's not an Application subclass. See Java: How do I start a standalone application from the current one when both are in the same package?

Community
  • 1
  • 1
James_D
  • 201,275
  • 16
  • 291
  • 322
  • Hi James, thanks a lot for your response, it certainly helped clear a few things up. The reason I wanted to use the tester method, was because I was planning on having a number of buttons on a section of my GUI, clicking each one would launch a seperate video. Is there any way I can accomplish this? The controllers for all of the buttons lie in the same controller class. – freshwaterjoe Feb 09 '16 at 00:11
  • Make the class encapsulating the web view just a regular class, I.e. Not a subclass of `Application `. Then just reference it in the button handlers. This is very similar to the question I linked in the answer. – James_D Feb 09 '16 at 00:34