cannot read image in jar file: javafx - java

when I build a jar file an run it, i can't see the image.
In Eclipse it is working all good.
The Image should be a Button
<effect>
<ImageInput>
<source>
<Image url="file:./images/record_by_felickzs.PNG" />
</source>
</ImageInput>
</effect>

that is because on eclipse the image is not packed so it is accessible the way you are doing it, however when you export a jar file the image is packed and you can not access file inside the jar that way,,, use relative path instead:
<effect>
<ImageInput>
<source>
<Image url="#../../images/record_by_felickzs.PNG" />
</source>
</ImageInput>
</effect>
edit : replace PNG with png

Related

JavaFx imageview can't resolve file error

I've been struggling with this problem regarding JavaFx ImageView class. the code written in fxml
<ImageView fitHeight="634.0" fitWidth="1204.0" layoutX="38.0" layoutY="83.0" pickOnBounds="true" preserveRatio="true" rotate="-8.0">
<image>
<Image url="#\PCI%20logoRYB.png" />
</image></ImageView>
and it keeps showing this error
Cannot resolve file '\PCI%20logoRYB.png'
I created all this using scene builder and the image is at the same place as the fxml file/s
Try remove \ from your url, like below. Image must be in the resources directory.
<ImageView fitHeight="634.0" fitWidth="1204.0" layoutX="38.0" layoutY="83.0" pickOnBounds="true" preserveRatio="true" rotate="-8.0">
<image>
<Image url="#PCI%20logoRYB.png" />
</image></ImageView>
if you are using eclipse IDE after adding resources like images you need to clean your project to reload all new resource files which was added to project.

Changing from FileReader to getResourceAsStream

When I tried loading my little game from a .jar file the fileReader would no longer work and I was advised to use the getResourceAsStream function instead, when I run the code bellow in the IDE it works fine so the path is correct, when I change to the getResourceAsStream which is currently commented out and remove the file reader line, I get these errors.
Exception in thread "Thread-0" java.lang.NullPointerException
at java.io.Reader.<init>(Reader.java:78)
at java.io.InputStreamReader.<init>(InputStreamReader.java:72)
Is there a way that I can fix this?
public class Utils {
public static String loadFileAsString(String path) {
StringBuilder builder = new StringBuilder();
try{
//InputStream is = Utils.class.getResourceAsStream(path);
//BufferedReader br = new BufferedReader(new InputStreamReader(is));
BufferedReader br = new BufferedReader(new FileReader(path));
String line;
while((line = br.readLine()) != null)
builder.append(line + "\n");
br.close();
}catch(IOException e){
e.printStackTrace();
}
return builder.toString();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/res" isTestSource="false" />
</content>
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library">
<library>
<CLASSES>
<root url="file://$MODULE_DIR$/res" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="module-library" exported="">
<library>
<CLASSES>
<root url="file://$MODULE_DIR$/res/worlds" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
</component>
</module>
You need to start understanding what you're doing, what the classpath is, how Java loads classes, and how an app is bundled.
When you start a Java program, you use a command looking like this:
java -cp /some/directory:/some/file.jar com.foo.bar.Main
Given the above command, java will try loading the main class (and all the other classes used in your code) in two locations:
the /some/directory directory
the jar file /some/file.jar
Since the class is named Main, and is in the package com.foo.bar, it will thus look for a file named /some/directory/com/foo/bar/Main.class and if it doesn't find it, it will look inside the jar file for an entry /com/foo/bar/Main.class.
When you use SomeClass.getResourceAsStream("/res/worlds/world1.txt"), it will apply the same strategy: look for a file /some/directory/res/worlds/world1.txt and if not found, look inside the jar file for an entry /res/worlds/world1.txt.
So, since you use an IDE to run the project, you need to understand how an IDE works: what command does it use to start your program. The principle is quite simple:
there is a target directory where the IDE puts the .class files it generates from the source .java files. This target directory is part of the classpath when running the program for the IDE
there is also a target directory where the IDE stores all the files that are not .java files, and are located under a directory in IntelliJ marked as "Resources root". This target directory is also part of the classpath.
The structure in the target directory always respects the structure of the source/resource directory.
When packaging the app as a jar file, you'll end up with a jar file containing everything located under these target directories.
By default, in a basic IntelliJ project, your src directory is also a resources root. So every file you put there ends up in the target directory, and is thus available in the classpath, both when launching from the IDE, and when the target directory is packaged as a jar. You should just put the file somewhere under the src directory, and not mess with dependencies. Your txt file is part of the sources of the project, just like a Java file. It's "compiled" by the IDE by copying it to the directory, along with the .class files.

Embedded font don't work in Apache FOP

I am using FOP to tranform xml to pdf, and I need to use Chinese characters.I did do something to use Chinese font,but it seems don't work at all.
I create the font xml file.
and registered in the fop.xconf
<font metrics-url="/home/zhufree/Tools/fop-2.1/conf/simkai.xml" kerning="yes" embed-url="/home/zhufree/Tools/fop-2.1/conf/kaiti.ttf">
<font-triplet name="simkai" style="normal" weight="normal" />
<font-triplet name="simkai" style="normal" weight="bold" />
<font-triplet name="simkai" style="italic" weight="normal" />
<font-triplet name="simkai" style="italic" weight="bold" />
</font>
the font xml file and font ttf file are in the same directory with fop.xconf,when I try to transform,it still show me cant find the font.
What should I do to show the Chinese character?
Update:
I solved the problem by using specific configuration file in java code, and it worked well.Thanks.

Getting an FXML window to open when running a java file

I am currently trying to build a picture viewing program using java and an FXML window. I have had a fiddle about - getting to know FXMLs and accessing them from a program and was able to get buttons to disappear and reappear - but upon adapting said code for this picture viewer, I found that the FXML panel wouldn't open upon running the file. There are no errors/warnings besides warnings about (as yet) unused libraries being declared. Upon start up, there's no error messages, no text boxes and no outputs to the terminal so I can't supply anything from there. The code is as follows:
package practice1;
import javafx.application.Application;
import javafx.stage.Stage;
import java.io.IOException;
import javax.imageio.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.*;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.*;
import javafx.scene.image.ImageView;
import javafx.scene.image.*;
import java.awt.image.BufferedImage;
public class MainProgram extends Application{
public void start(Stage stage) {
try {
FXMLLoader fxmlLoader = new FXMLLoader();
String viewerFxml = "WindowPanel.fxml";
AnchorPane page = (AnchorPane)fxmlLoader.load(
this.getClass().getResource(viewerFxml).openStream());
Scene scene = new Scene(page);
stage.setScene(scene);
stage.show();
} catch (IOException ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
System.exit(1);
}
}
public static void main(String args[]) {
launch(args);
System.exit(0);
}
}
And the FXML is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="practice1.MyController">
<children>
<Button fx:id="TurnLeft" layoutX="113.0" layoutY="353.0" mnemonicParsing="false" onAction="#hide1" text="Turn Left" />
<Button fx:id="TurnRight" layoutX="237.0" layoutY="353.0" mnemonicParsing="false" onAction="#hide2" text="Turn Right" />
<ToolBar prefHeight="40.0" prefWidth="600.0">
<items>
<MenuButton mnemonicParsing="false" text="Pick Up">
<items>
<MenuItem mnemonicParsing="false" text="Action 1" />
<MenuItem mnemonicParsing="false" text="Action 2" />
</items>
</MenuButton>
<MenuButton mnemonicParsing="false" text="Drop">
<items>
<MenuItem mnemonicParsing="false" text="Action 1" />
<MenuItem mnemonicParsing="false" text="Action 2" />
</items>
</MenuButton>
</items>
</ToolBar>
<Button fx:id="proceed" layoutX="178.0" layoutY="315.0" mnemonicParsing="false" onAction="#changeImage" text="Proceed" />
<ImageView fx:id="mainImage" fitHeight="259.0" fitWidth="426.0" layoutY="40.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#Picture1.png" />
</image></ImageView>
<Text layoutX="436.0" layoutY="60.0" strokeType="OUTSIDE" strokeWidth="0.0" text="You have" />
<Text layoutX="436.0" layoutY="86.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Object1" />
<Text layoutX="436.0" layoutY="111.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Object2" />
<Text layoutX="436.0" layoutY="139.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Object 3" />
<ImageView fx:id="SmallImage2" fitHeight="89.0" fitWidth="117.0" layoutX="266.0" layoutY="45.0" pickOnBounds="true" preserveRatio="true" />
<ImageView fx:id="SmallImage3" fitHeight="89.0" fitWidth="117.0" layoutX="266.0" layoutY="142.0" pickOnBounds="true" preserveRatio="true" />
<ImageView fx:id="SmallImage1" fitHeight="89.0" fitWidth="117.0" layoutX="152.0" layoutY="45.0" pickOnBounds="true" preserveRatio="true" />
</children>
</AnchorPane>
The file "Picture1.png" is located in the workspace with the position being:
WorkspaceA/Practice1/scr/practice1/Picture1.png
Background
The # notation is used in JavaFX to specify a relative location which is "assumed to be located at a path relative to the current FXML file".
What is Wrong
You load the FXML as a stream using the following code:
AnchorPane page = (AnchorPane)fxmlLoader.load(
this.getClass().getResource(viewerFxml).openStream());
A steam is not a location, so there is no concept of locations relative to the stream.
If I run your application locally, I will get a stack trace where it cannot find the picture file (here is just the last portion of it):
Caused by: java.lang.IllegalArgumentException: Invalid URL or resource not found
at javafx.scene.image.Image.validateUrl(Image.java:1081)
... 18 more
How to fix it
Set the location in the loader prior to loading the FXML:
fxmlLoader.setLocation(getClass().getResource(viewerFxml));
AnchorPane page = fxmlLoader.load();
The loader will then be able to resolve the relative reference to your picture file.
Check your directory structure and build output
This may or may not be an issue for you.
You specify your image using the location specifier:
<Image url="#Picture1.png" />
Which tells the FXMLLoader to look for Picture1.png at the same location it got the FXML from; e.g. if you loaded the FXML from the filesystem, the image would be in the same folder on the filesystem as the FXML - similarly if you load the FXML from a jar, the image should be on the same path within the jar as your FXML was retrieved from.
You state that you place your picture at: WorkspaceA/Practice1/scr/practice1/Picture1.png. I'm not sure what that location is, but if it is the same location as your MainProgram.java source, your MyController.java source, WindowPanel.fxml and if your build system is set to copy the image and fxml over to the compile and packaging target directory, then it will work fine - if it's not, you will need to move the image to the appropriate source location.

Container for image

I'm programming a app with JavaFX and Scene Builder. I want to create a container and insert an image inside.
But, the container have a size so if the image goes out that limits you can't see this image.
For Example, make a container and make the image too much bigger outside that, but just see what is inside the container.
Is that possible?
Solution
Use an ImageView (which is a node container for an Image). You can set a viewport on the ImageView to have the view render a specific part of an image.
Alternative Implementation
Specify your image in CSS and use combinations of -fx-background-image, -fx-background-repeat, -fx-background-position and -fx-background-size as defined in the JavaFX CSS reference guide.
The rest of this answer deals with just the FXML based solution and not the CSS based solution.
Code Based Sample
Here is a code snippet (adapted from the ImageView javadoc) which demonstrates setting a viewport in code:
Image image = new Image("flower.png");
ImageView view = new ImageView();
view.setImage(image);
Rectangle2D viewportRect = new Rectangle2D(40, 35, 110, 110);
view.setViewport(viewportRect);
FXML Based Sample
Here is some FXML to demonstrate the viewport approach.
<ImageView pickOnBounds="true">
<image>
<Image url="http://icons.iconarchive.com/icons/vincentburton/diaguita-ceramic-bowl/128/Diaguita-Ceramic-Bowl-4-icon.png" />
</image>
<viewport>
<Rectangle2D minX="35.0" minY="55.0" width="55.0" height="40.0" />
</viewport>
</ImageView>
Here is a complete example which you can load up into SceneBuilder. The first ImageView displays an unclipped image, the second ImageView displays a clipped image.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.geometry.Rectangle2D?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<StackPane id="StackPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="-1.0" prefWidth="-1.0" style="-fx-background-color: burlywood;" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2">
<children>
<VBox alignment="CENTER" prefHeight="-1.0" prefWidth="-1.0" spacing="10.0" style="-fx-background-color: cornsilk;">
<children>
<ImageView pickOnBounds="true">
<image>
<Image url="http://icons.iconarchive.com/icons/vincentburton/diaguita-ceramic-bowl/128/Diaguita-Ceramic-Bowl-4-icon.png" />
</image>
</ImageView>
<ImageView pickOnBounds="true">
<image>
<Image url="http://icons.iconarchive.com/icons/vincentburton/diaguita-ceramic-bowl/128/Diaguita-Ceramic-Bowl-4-icon.png" />
</image>
<viewport>
<Rectangle2D height="40.0" minX="35.0" minY="55.0" width="55.0" />
</viewport>
</ImageView>
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</VBox>
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</StackPane>
On using the FXML Based Sample in SceneBuilder
To generate the FXML, the majority of the work was done in SceneBuilder, but setting the viewport was done by hand editing the FXML saved from SceneBuilder (because SceneBuilder 1.1 does not possess the UI to set the viewport on ImageViews from within the SceneBuilder tool). After hand-editing the FXML to add the viewport, you can reload the FXML in SceneBuilder and SceneBuilder will render the viewport in the hand-edited FXML fine.
Also, SceneBuilder 2 build 14 preview did not display images that are located using the http protocol (SceneBuilder 1.1 did not have an issue with this).
Attribution
Icon used in the answer is licensed CC Attribution-Noncommercial-Share Alike 3.0 with a linkback to the icon author.

Categories