JavaFX - Cannot Load Image Inside Project Directory - java

I am using netbeans. I have a project directory like this:
HTMLEdit/
src/
htmledit/
- pic.png
- MyClass.java
I tried to get the image, but it return null. I had trying both of these but still cannot get it to work:
System.out.println(getClass().getResourceAsStream("/pic.png"));
and
System.out.println(getClass().getResourceAsStream("pic.png"));
What's causing this weird behavior?
EDIT :
It looks like it's because I choosed JAVAFX Project when created the project. I recreate the project by choosing Java Project and it works fine. May be this is Netbeans bug.

getClass().getResourceAsStream() is used for files embedded inside your java jar file. You should use FileInputStream if you need to read a file from your file system as a stream of bytes. Here's the documentation: https://docs.oracle.com/javase/8/docs/api/java/io/FileInputStream.html

When you do getClass().getResourceAsStream("/pic.png")then the url that will be looked to access the file will be an absolute url. The absolute URL is indicated by the slash which is at the front of the resource location.
If you do getClass().getResourceAsStream("pic.png"), then a resource relative to the package where the class resides will be used.
Because you said that both of the getResourceAsStream() statements did not work in Netbeans, I checked the below JavaFX code in Netbeans and it worked perfectly.
public class MyClass extends Application{
#Override
public void start(Stage primaryStage) {
Pane root = new Pane();
Image images = new Image(getClass().getResourceAsStream("pic.png"));
ImageView image = new javafx.scene.image.ImageView(images);
root.getChildren().add(image);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Here is the structure and the output of the program.
In case if you want to know the Netbeans version, I am using then it is Netbeans 8.0.2.
Also, read the following post.
Different ways of loading a file as an InputStream

Related

JavaFX-maven project suddenly stopped recognizing resources on InteliJ IDE

Yesterday my JavaFX-maven project was working fine in InteliJ IDE, but packed JRE with maven javaFX:jlink command was throwing similar exeption to this one I`ve got today with javaFX:run command:
Caused by: java.lang.IllegalArgumentException: Invalid URL: Invalid URL or resource not found
at javafx.graphics/javafx.scene.image.Image.validateUrl(Image.java:1125)
at javafx.graphics/javafx.scene.image.Image.<init>(Image.java:618)
at javafx.graphics/javafx.scene.image.ImageView.<init>(ImageView.java:194)
at org.example/org.example.GameMenu.construct(GameMenu.java:20)
at org.example/org.example.App.start(App.java:23)
The code that throws exeption:
public class GameMenu {
static int picOfChoice = (int) (Math.random() * 6);
public static Font font = Font.loadFont(Objects.requireNonNull(GameMenu.class.getResource("/utility/pixRectv2.ttf")).toExternalForm(), 48);
public static Font font2 = Font.loadFont(Objects.requireNonNull(GameMenu.class.getResource("/utility/pixRectv2.ttf")).toExternalForm(), 32);
public static Group menu = new Group();
public static Group construct() {
menu = new Group();
ImageView logo = new ImageView("menu/logo3.png");
Image backg3 = new Image("backg/backgPL" + picOfChoice + ".png", winWidth, winHeight, false, false);
ImageView backgV3 = new ImageView(backg3);
menu.getChildren().add(backgV3);
logo.setX(0);
logo.setY(0);
menu.getChildren().add(logo);//Logo is on top
return menu;
}}
No code on that line was changed. Resources folder was not moved. pom.xml wasnt changed. Those png`s are accesible for R/W and
even recognized by IDE as images
I have tried different path formatting (absolute path included) and it did not help. But ImageView logo = new ImageView("file:menu/logo3.png"); loads no image, while not throwing any exeption.
I have tried opening my other javaFX projects and they all work, while using similar project structure and similar way of useing new ImageView(). I have created new project with javaFX and it loads images just fine, so I wasnt able to recreate this problem.
I have opened this project on other machines, it throws same exeptions.
Fonts of javaFX in code above still load fine. Similar way of loading images ( through GameMenu.class.getResource ) works too.
The question: How to fix it and how to avoid it in future?
My project folder tree
UPD:
Thanks to #James_D and #Dmitriy Popov for answers;
I have added new method for path extraction via widely used .class.getResource()
So fixed code looks like
ImageView logo = new ImageView(Utility.getImageRes("/menu/logo3.png"));
Where Utility.getImageRes(String) is
public static String getImageRes(String path) {
return Objects.requireNonNull(Utility.class.getResource(path)).toExternalForm();
}
It works now, both with javaFX:run and jlink commands. Reason why previous method stopped working is still unknown.

JavaFX is not displaying JPG files

For some reason, my application is not showing JPG files within a JavaFX window. It does not matter if I'm trying to display the image inside an ImageViewer node or setting it as a background with the CSS -fx-background-image: url(...); property.
I have tried with different jpg files. It did not work.
I have tried with different image extensions (png, gif). It did work.
I'm using OpenJDK 16+36 (I tested with Hotspot and OpenJ9 JVM), JavaFX 16, my operating system is Linux 5.11.16 and my window manager is GNOME Shell 3.38.4.
PS: Needless to say, the operating system handles JPG images without any problems.
What could be causing this behavior?
Edit 1:
For me, nothing that involves jpeg is working on JavaFX. Wether I try to use jpeg as an background-image, like this very Oracle's sample, or within an ImageViewer, the result is the same (the window opens normally, as if I hadn't put any image). If I replace the file with a different extension, it works perfectly. The funny thing is that jpeg is working without issues in Swing.
Here's one sample of the possible situations in which the issue happens:
/**
* JavaFX Application
*/
#Override
public void start(Stage primaryStage) throws Exception {
// opens a window with the image without issue and prints true
var fileUrl = getClass().getResource("/freemind.png");
var image = new Image(fileUrl.toExternalForm());
var imageViewer = new ImageView(image);
var vbox = new VBox(imageViewer);
var scene = new Scene(vbox);
primaryStage.setScene(scene);
primaryStage.show();
System.out.println(new File(fileUrl.getFile()).exists());
}
But when I replace the fileUrl with another existing jpg file, in the same directory, it opens a blank window, and prints true.
Edit 2:
I found the -Dprism.verbose=true -Djavafx.verbose=true debug flags, which were unknown to me, and they print the problem:
Stack trace here
Some JPEG library, which I am not sure whether it comes embedded in the JavaFX SDK or is related to the operating system is in a different version than the expected. Now, which library is that, I don't know!
rpm -qa | grep -P jpe?g returns:
libjpeg-turbo-2.0.5-5.fc33.i686
libjpeg-turbo-2.0.5-5.fc33.x86_64
libjpeg-turbo-devel-2.0.5-5.fc33.x86_64
mjpegtools-libs-2.1.0-20.fc33.x86_64
openjpeg2-2.3.1-10.fc33.x86_64

Setting stage icon

My first intention was to set TextInputDialog icon. But I started from setting stage icon. I saw couple SO questions with marvelous answers containing usually 2 lines of code.
First I tried to put this icon to /resources/icons but exception "Invalid URL or resource not found" appeared. To be sure I don't make any mistake writing file path I moved this icon to /source/sample directory. I use code (I will post whole code):
public void start(Stage stage) throws Exception {
FXMLLoader loaderModyfikacjaKonfiguracji = new FXMLLoader(getClass().getResource("FXMLModyfikacjaKonfiguracji.fxml"));
Parent root = loaderModyfikacjaKonfiguracji.load();
stage.setTitle("Modyfikacja konfiguracji");
Image image = new Image("file:icon.png");
//stage.getIcons().removeAll();
stage.getIcons().add(image);
ControllerModyfikacjaKonfiguracji controllerModyfikacjaKonfiguracji = loaderModyfikacjaKonfiguracji.getController();
stage.setScene(new Scene(root, 510, 700));
stage.show();
}
Everywhere it looks so simple to set icon. I also tried .jpg. not using file: throws exception, using file: compiles but I see no effect of changed icon. What am I doing wrong or where is the problem?
I've successfully used this to set an icon before
primaryStage.getIcons().add(new Image(getClass().getResourceAsStream("AppIcon.png")));
In my case, the application fxml file and AppIcon.png are in the same directory.
If you dont want to go that route, i would suggest trying
Image image = new Image("file:./icon.png");
But that's a guess.

JavaFX Cannot Find Image

just started a new project and am already running in to some issues. I am trying to display an image with javafx but the compiler is complaining that the provided location is invalid. Here is all of my code so far (apart from some imports):
public class main extends Application{
public static void main(String[] args) {
launch(args);
}
public void start(Stage primaryStage) throws Exception{
Stage stage = primaryStage;
String version = "alpha";
stage.setTitle("Space Invaders v. " + version);
VBox vbox = new VBox();
Image pic = new Image("Art\\whiteMonster.jpg");
ImageView image = new ImageView(pic);
vbox.getChildren().add(image);
Rectangle rect = new Rectangle(20,0,200,200);
rect.setFill(Color.BLACK);
vbox.getChildren().add(rect);
//Creating the scene.
Scene scene = new Scene(vbox);
stage.setScene(scene);
stage.show();
}
}
If I change the file path to the images url where I found it in google image search it displays the black rectangle added beneath it (just to test if everything works) but not the image. In the current configuration however it simply throws an error saying the URL is either invalid or that the resource was not found. What makes me think that this should work is this example here: https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/ImageView.html
Thanks for any help.
PS. I've been looking at other similar questions here but haven't found anything that helped me and if you feel like you need any other information give me a shout.
-----EDIT-----
Project Structure, Code and File Manager, all images are placed directly in the "Art" folder.
I hope that is all you need.
Try putting the image inside the folder .Drag the image to the "src" and use Image pic = new Image("whiteMonster.jpg");. It should be displayed under the .java files but a little bit in the left.
The solution for me was to Close Project and open the Javafx Project
again
as shown here
This refreshes the images URL for Javafx.
NOTE: I am using Intellij IDEA Java version 16 with Javafx.
Error was: Caused by: java.lang.IllegalArgumentException: Invalid URL or resource not found

Getting a mp3 file to play using javafx

I have spent hours today looking up how to get some form of audio in eclipse and have had trouble every step of the way. Currently I have something that should work but I get an error:
Exception in thread "main" java.lang.IllegalArgumentException: expected file name as argument
at com.sun.javafx.css.parser.Css2Bin.main(Css2Bin.java:44)
I have basically copied this from someone who had it working. I would like to say that the FX lib is added where it should be. I know this isn't fancy but I was just trying the basics.
package b;
import java.io.File;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
public class test {
public static void main(String[] args){
String uriString = new File("C:\\Users\\Mike\\workspace\\b\\src\\hero.mp3").toURI().toString()
MediaPlayer player = new MediaPlayer( new Media(uriString));
player.play();
}}
I have also tried many different path names in case it was wrong with no luck, I also just tried to copy and paste the path name that i got in eclipse by going to properties ex: /b/src/hero.mp3. Help would be appreciated to get me out of this nightmare.
The files located outside the workspace should be included with file:// prefix. A simple example demonstrating the functionality is
public class Reproductor extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
Media media = new Media("file:///Movies/test.mp3"); //replace /Movies/test.mp3 with your file
MediaPlayer player = new MediaPlayer(media);
player.play();
}
}
If the file is into the resources/music this will work and the application will be portable,.mp3 inside the .jar:
Media media = null;
try {
media = new Media(getClass().getResource("/music/hero.mp3").toURI().toString());
} catch (URISyntaxException e) {
e.printStackTrace();
}
I suspect you have a issue with referencing embedded resources. An embedded resource is any file which is contained within the application context (ie. In this case, stored within the application Jar).
In order to obtain a reference to these resources, you need to use Class#getResource, which returns a URL, which you can then use to load the resource depending on your requirements, for example...
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
String path = Test.class.getResource("/Kalimba.mp3").toString();
Media media = new Media(path);
MediaPlayer mp = new MediaPlayer(media);
mp.play();
System.out.println("Playing...");
}
public static void main(String[] args) {
launch(args);
}
}
Now, I couldn't get it to work until I wrapped in a Application context...
JavaFX EMBED an MP3 into the jar (in the jar) with NetBeans
I programmed my very first JavaFX package in NetBeans, and then I wanted to add sound, an mp3 music file, embedded in the jar, inside the jar, so that I could email the jar to my friends and the music would play on their computers. Thank you StackOverflow for your help. Thanks especially to the member who said “put your music file IN THE JAR, getResourceAsStream() is the API you want to use.” He put me on the right track, although I ended up using getResource(). It works.
STEP 1: Firstly, I got the music to play when I hit run in NetBeans.
STEP 2: I wanted the music to loop (repeat). Eventually I got that right, thanks to the members of StackOverflow. Please see my source code.
STEP 3: Finally I got the mp3 to EMBED in the jar. Now, this is important. At first the music played on my computer, but the jar read it off my hard disc. When I changed the name of the mp3, then the jar crashed, it would not run, it could not find the mp3. I had to embed the mp3 into the jar, put it inside the jar (in the jar) otherwise it would not play on somebody else’s computer. That’s where getResource() did the trick.
STEP 4: Then I emailed my jar to friends. Some service providers don’t trust a jar, they sent the emails back to me, undelivered. Other service providers don’t have a problem and delivered the emails. So, what did I do? I changed the name of the *.jar to *.mp4 and the emails were delivered, I asked my friends to change it back from *.mp4 to *.jar. It worked.
Here is my source code. I’m sure it’s not perfect, but it works, thanks to StackOverflow.
/* Of course, one needs to import the following gizmo’s (and others): */
import javafx.util.Duration;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
/* I want to EMBED the music inside the jar (in the jar).
The secret seems to be getResource. The source code starts here,
to EMBED the sound (DollyParton.mp3) into the jar: */
//************************ begin the music ***********************
#Override public void start(Stage primaryStage) throws Exception {
init(primaryStage);
primaryStage.show();
play();
}
public static void main(String[] args) {
launch(args);
}
MediaPlayer musicplayer; {
/* Put your music file IN THE JAR, "getResourceAsStream()" is
the API you want to use. Put the DollyParton.mp3 into the Windows
folder src/rockymountain. NetBeans automatically copies the mp3
to the folder build/classes/rockymountain. */
Media mp3MusicFile = new Media(getClass().getResource("DollyParton.mp3").toExternalForm());
musicplayer = new MediaPlayer(mp3MusicFile);
musicplayer.setAutoPlay(true);
musicplayer.setVolume(0.9); // from 0 to 1
//***************** loop (repeat) the music ******************
musicplayer.setOnEndOfMedia(new Runnable() {
public void run() {
musicplayer.seek(Duration.ZERO);
}
});
//*************** end of loop (repeat) the music **************
}
//**************************** end of music *************************
I put the mp3 into the Windows folder src/rockymountain. Then NetBeans automatically copied the mp3 to the folder build/classes/rockymountain. NetBeans does not copy the mp3 to the folder /resources, a file that I created unnecessarily, because someone said so. The /resources folder is not needed, it remains empty.
Create a Java ARchive (jar) file using NetBeans as follows:
Right-click on the Project name
Select Properties
Click Packaging
Check Build JAR after Compiling
Check Compress JAR File
Click OK to accept changes
Right-click on the Project name
Select Clean and Build
The JAR file is built. To view it inside NetBeans:
Click the Files tab
Expand ProjectName >> dist (distribution). The jar file is inside the dist folder.
Try to add --add-modules=javafx.controls,javafx.media in your VM options.
I tried this three lines and it worked!
Media sound = new Media(new File("src/music/menu.mp3").toURI().toString());
MediaPlayer player = new MediaPlayer(sound);
player.play();
First you need to put the code in try and catch to catch any error, second you must
define the JFXPanel to define it to the media package and the tool kit ,so this is the code:
package test1;
import java.io.File;
import javafx.scene.media.Media;
import javax.swing.JOptionPane;
import javafx.scene.media.MediaPlayer;
import javafx.embed.swing.JFXPanel;
public static void main(String[] args) {
try {
JFXPanel j = new JFXPanel();
String uriString = new File(""C:\\Users\\Mike\\workspace\\b\\src\\hero.mp3"").toURI().toString();
MediaPlayer Player = new MediaPlayer(new Media(uriString));
Player.play();
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex);
}
}
and a good info for you can put only file name
inside the File() exp: String uri = new File("hero.mp3").toURI().toString();

Categories