JavaFx FileChooser without Stage - java

I am in the process of learnig JavaFx, and I encountered a problem. I was trying to use FileChooser from JavaFx the way I was used to working with JFileChooser from Swing-in the main() method. However I found out that I need a Window object. I've tried searching for a workaround, but I found none. I've also tried null (as you do in JFileChooser) and new Stage(), so those are off the table. I was trying to mimic the JFileChooser.showOpenDialog(). Is there any reasonable way to make it work?

The main method is not executed on the FX Application Thread, so you can't show a FileChooser from it. (You can't really do that in Swing either, unless you are using SwingUtilities.invokeLater(...).)
In JavaFX, the responsibility for starting the application is in the start() method, which is executed on the FX Application Thread. (In many runtime environments, you don't even need a main method in JavaFX applications.)
Just show the file chooser from the start method, where you have access to the primaryStage (or can just pass null, if you like):
public class MyApp extends Application {
public void start(Stage primaryStage) {
FileChooser configFileChooser = new FileChooser();
File configFile = configFileChooser.showOpenDialog(primaryStage);
// ... parse file and create UI, etc...
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Related

java.lang.NoClassDefFoundError when using JavaFX for playing sound from jar

I want to be able to play sound from mp3 files for which I saw posts recommending the usage of JavaFX. I implemented the MediaPlayer and initialized the JFXPanel and in eclipse, everything works lovely.
Yet when I export to a runnable jar, and try running the program, I get the following error message: java.lang.NoClassDefFoundError: javafx/scene/media/MediaException.
I presume this is from the exclusion of JavaFX in the newer JRE versions (which I came across during my search to a solution). My main question is how do I ship the jar with JavaFX? Do I have to include a jar, and if yes, where do I get it? Because eclipse doesn't seem to package JavaFX into my runnable if I'm not mistaken.
Here an example which, for me, already triggers this behavior:
// This would throw a java.lang.NoClassDefFoundError for the JFXPanel but is effectively the same problem
public class Test extends Application
{
public static void main(String[] Args)
{
launch(Args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Hello World!");
StackPane root = new StackPane();
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
}
Thank you for your help!
JavaFx was removed into JDK> = 11 and now is a separate project opensurse [openjfx] (https://openjfx.io/).
And now it is to be made more difficult to create a version of the application javafx runnable everywhere, but it is a continuous evolution and I think that this is good documentation [doc-image-live] (https://openjfx.io/openjfx-docs/#modular).
I had a problem simile when I used for the developing the JDK 1.8 but in my version java system is openjdk11, I think this is the same case.
Your example is wrong because not is a JavaFX application.
The JavaFX application must extend the javafx.application.Application and in the main call the method launch, this method will call the method start inherited from Application.
This is a simple example of the Oracle
public class HelloWorld extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Hello World!");
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
}
ps: When you speak the javafx, you must add the java version because we don't know your java version
An alternative path, if you prefer to not use JavaFX, would be to make use of the libraries that originated from JavaZOOM for the task of reading the mp3 files. I am seeing many offerings on github that have been derived from this source, for example, https://github.com/goxr3plus/java-sound-libraries But I have not made use of this particular library myself.
My preference has been to combine JavaFX for GUI with javax.audio.sampled, and a library I built that relies on java.sound.sampled.SourceDataLine for output. But I never bothered to implement reading mp3s. I tend to take the ogg/vorbis route when using compressed audio resources.

JavaFX FileChooser initial directory

In Swing, the JFileChooser pointed to the user's default directory which is typically the "My Documents" folder in Windows. The JavaFX FileChooser does not have the same behavior by default. There is a setInitialDirectory method which should be fine, however there are a number of places in the application that we open FileChoosers. Unfortunately the FileChooser class is final, so I cannot simply extend the class and just call the setInitialDirectory once. Is there anything else I could do besides going through the entire application and adding the setInitialDirectory calls?
There's the obvious solution, to just create a static utility method somewhere:
public class MyUtilities {
public static FileChooser createFileChooser() {
FileChooser chooser = new FileChooser();
chooser.setInitialDirectory(new File(System.getProperty("user.home"));
return chooser ;
}
}
Then you can just do
FileChooser chooser = MyUtilities.createFileChooser();
whenever you need one.
I actually prefer, from a user experience perspective, to use a single FileChooser instance for the whole application (or at least for each functional portion of a large application). That way it maintains the last directory the user visited, which is more convenient imho.

UISpec4J and external application

I am trying to launch an external application for testing using UISpec4J.
Here are the questions and their answers I referred so far:
How to automate a swing java web start application which runs clicking a link into a web application, which is automated with Selenium WebDriver?
Getting all windows using UISpec4J
UISpec4J Capturing modal dialog, before the trigger finish
my.exe referred below is a Java application wrapped in exe using some tool. Internally it uses the jars and is Java GUI application.
This executable launches a splash screen first, then a dialog to choose where you want to connect to and after that main window is shown. Unless I can automate where I can connect to I won't get main window.
Based on these questions I have come up with following code fragments:
this.setAdapter(new UISpecAdapter() {
#Override
public Window getMainWindow() {
return WindowInterceptor.run(new Trigger() {
#Override
public void run() throws Exception {
// running jnlp by netx launcher
Runtime.getRuntime().exec("C:\\my.exe");
Thread.sleep(10000);
}
});
}
});
In the approach above I simple get "No window was shown" error.
this.setAdapter(new UISpecAdapter() {
#Override
public Window getMainWindow() {
final Window[] result = new Window[1];
WindowInterceptor
.init(new Trigger() {
#Override
public void run() throws Exception {
Runtime.getRuntime().exec("C:\\my.exe");
//Thread.sleep(10000);
}
})
//.processTransientWindow()
.process(new WindowHandler() {
public Trigger process(Window window) throws Exception {
result[0] = window;
return Trigger.DO_NOTHING;
}
})
.run();
return result[0];
}
});
In the second approach above, I still get "No window shown" error AND control never reaches to overriden "process" method.
I referred to http://www.uispec4j.org/reports/apidocs/org/uispec4j/interception/WindowInterceptor.html and recommended approach is to use init to capture modal dialog is init\process sequence.
To capture non-modal it is recommended that we should use following:
Window window = WindowInterceptor.run(panel.getButton("open").triggerClick());
But I have NO idea where and how I am supposed to call it..
From the first question I referred, mentioned above, we should be able to do that because the answer to it mentions launching jnlp application which is external application.
I tried with jre 6 update 0 and I can at least run test. In java update 37, from the third question I referred above, I get abstract method not implemented error.
What am I doing wrong? Any idea?
I am using latest UISpec4J package - version 2.4.
Thanks in advance,
-Neel.
I'm very new to UISpec4J but I'm guessing it needs to run in the same JVM in order to intercept and interact with the GUI components. When you start the exe file with exec, it will create a new process and a new, separate JVM. That'll not work, if I understand UISpec4J correctly.
Regarding the non-modal example, the documentation says "You would retrieve the window from within the test...", so in a setup method or in a test should work.

Internal graphics not initialized yet: javafx

I'm trying to write a javaFx application whit multiple images inside a window.
The short story is that I have an enum class named Candy and each candy has some properties and a path to the image file representing it.
In the constructor of my javafx.application class (Table) I want to fill an array list with those images, so I wrote this so far:
public class Table extends Application {
ArrayList<Image> images;
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("CandyFx");
primaryStage.show();
}
public Table() {
images = new ArrayList<Image>();
for (Candy candy : Candy.values()) {
File file = new File (candy.getImagePath());
Image image = new Image(file.toURI().toString());
images.add(image);
}
}
}
Now every time I want to create an instance of Table class, the application throws a java.lang.RuntimeException: Internal graphics not initialized yet.
How can I initial graphics which it seems I did not?
First of all if you are using linux ,GTK 2.18 is required to run JavaFX .try to install
libswt-gtk-3-java
This exception will thrown whenever your screen is null .Try to create your images inside start method. Just before the primaryStage.show();.
Take a look at this link too
http://cr.openjdk.java.net/~vadim/RT-33475/webrev.00/modules/graphics/src/main/java/com/sun/glass/ui/Screen.java.html
I have no idea how it exactly works, but when we first create a JFXPanel in our start we don't get the errors anymore.
JFXPanel jfxPanel = new JFXPanel();
Actually, JavaFX Stage class is the top level JavaFX container which should be constructed and modified on the JavaFX Application Thread.
Here you are using Stage class but have not embed JavaFx content into Swing application which may show you a 'java.lang.RuntimeException with message Internal graphics not initialized yet.
Here you may use-
JFXPanel jfxPanel = new JFXPanel();
Or you may use in this way too.
JFrame frame = new JFrame("Java Swing And JavaFX");
JFXPanel jfxPanel = new JFXPanel();
frame.add(jfxPanel);
JFXPanel is a component to embed JavaFX content into Swing applications. The content to be displayed is specified with the setScene(javafx.scene.Scene) method that accepts an instance of JavaFX Scene. After the scene is assigned, it gets repainted automatically. All the input and focus events are forwarded to the scene transparently to the developer.
References:
JFXPanel: https://docs.oracle.com/javase/8/javafx/api/javafx/embed/swing/JFXPanel.html
Stage: https://docs.oracle.com/javase/8/javafx/api/javafx/stage/Stage.html

export a JOGL applet and embedd into a html page

It is some time that I'm testing opengl with java and JOGL. I have a good result and I wan to publish it on the web, but I have a problem. I'm in eclipse, and I'm testing an Applet with JOGL.
EDIT: Thanks to Ricket answer it fixed this problem
first of all i have this run time error (but the program works correctly):
java.lang.IllegalArgumentException:
adding a window to a container at
EDIT: but it still doesn't work:
then I found this incredibly clear page
and I did what is said. I open html with the browser, the libs are downloaded, but it stops at Starting applet AppletHelloWorld, as that is the name I gave to my applet.
Maybe I am missing something like a main function or exporting the jar properly?
This is my main code:
public class AppletHelloWorld extends Applet
{
public static void main(String[] args)
{
JFrame fr=new JFrame();
fr.setBounds(0,0,1015,600);
fr.add(new AppletHelloWorld());
fr.setVisible(true);
}
public void init()
{
setLayout(null);
MyJOGLProject canvas = new MyJOGLProject(); //MyJOGLProject extends JFrame
canvas.run(); // this do setVisible(true)
} //....
Just as the error says, you're trying to add a window to a container. A JFrame is a window. You can't add a JFrame to anything, including a Container. I think perhaps you either don't know what a JFrame is, or don't know what a Container is.
Ideally you would have MyJOGLProject extend GLEventListener instead. Then your init function would make a new GLCanvas, add an instance of MyJOGLProject to it (via addGLEventListener), and then add the GLCanvas to your applet.
Alternatively, if you're okay with the applet popping up a JFrame, then simplify your init method:
public void init() {
setLayout(null);
MyJOGLProject canvas = new MyJOGLProject();
canvas.setVisible(true);
}
That should do it.
Use JApplet. I think that's the reason why it fails.
(Use Webstart with JNLP in NetBeans)

Categories