Here is the method that's giving me trouble:
private static final String theURL = "/optimize/images/prun0.png";
public static void createChallenge() {
Stage challStage = new Stage();
Group challGroup = new Group();
Rectangle rect = new Rectangle(900, 500);
Image image = new Image(theURL);
System.out.println(image.getHeight()); //Prints 0.0
rect.setFill(new ImagePattern(image)); //Gives runtime error: "Image must be non-null"
challStage.setResizable(false);
challStage.setTitle("Optimize!");
//ImageView iv = new ImageView(image);
challGroup.getChildren().add(rect);
Scene challScene = new Scene(challGroup, 900, 500);
challStage.setScene(challScene);
challStage.setMinHeight(500);
challStage.setMinWidth(900);
challStage.show();
challStage.centerOnScreen();
challStage.setX(challStage.getX()-150);
}
As it says, it throws a runtime error about image being null. Am I missing something basic? Also, the ultimate goal here is to put an image onto a Stage or Scene. I tried to do it simply with adding ImageView objects to the defined challGroup, but the Stage came up blank. Due to this, I tried to add the image to a Rectangle object and there found the actual runtime error. I have thrice-checked the URL. I've also tried using "file:prun0.png" to similar results. Any advice is appreciated. Thanks to all.
Related
If I add some media (pictures and/or sounds) my JavaFX artifact won't launch.
Im using macOS and IntelliJ. Launching the .jar from Terminal returns "Error: Could not find or load main class". However, this only occurs with pictures I stored in variables but haven't included yet (for ex. a PlayerIcon) so it isn't a manifest issue.
I installed Java 8 because I got so many issues with Java 10, 11 and 12. Inside of IntelliJ the project launches normally, just the exported .jar is affected of the issue. I am new to JavaFX and I did not include a FXML file. Maybe that's the issue?
Heres a code snippet of how I included one image:
Image Scoreboard = new Image(getClass().getResourceAsStream("Scoreboard.png"));
ScoreBoardContainer.setImage(Scoreboard);
Group root = new Group();
root.getChildren().add(ScoreBoardContainer);
Scene GameUI = new Scene(root, w, h);
Thanks for your help!
Longer code snippet:
package sample;
import ...
public class Main extends Application {
...variables...
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
final ImageView HintergrundMuster = new ImageView();
final ImageView ScoreBoardContainer = new ImageView();
Image HG = new Image(getClass().getResourceAsStream("space-background.png"));
Image PlanetBraun = new Image(getClass().getResourceAsStream("Planet.png"));
Image Scoreboard = new Image(getClass().getResourceAsStream("Scoreboard.png"));
HintergrundMuster.setImage(HG);
ScoreBoardContainer.setImage(Scoreboard);
AudioClip SprungSound = new AudioClip(new File("jump.mp3").toURI().toString());
SprungSound.play(0);
Canvas canvas = new Canvas(b,h);
Vordergrund = canvas.getGraphicsContext2D();
Group root = new Group();
root.getChildren().add(HintergrundMuster);
root.getChildren().add(canvas);
root.getChildren().add(ScoreBoardContainer);
Scene GameUI = new Scene(root, b, h);
primaryStage.setTitle(„Test“);
primaryStage.setScene(GameUI);
primaryStage.show();
...
I just found the solution to my problem. Thanks for your help anyway!
I overlooked that some of my files had the .PNG format while others had .png. For IntelliJ, this doesn't matter, but for the JAR compiler it does indeed matter apparently.
Also, I had a problem with my audio files so I copied them into my "sample" folder and changed the code a little bit. Following snipped worked for me:
AudioClip SprungSound = new AudioClip(this.getClass().getResource("jump.mp3").toString());
When trying to show an image stored in the system clipboard, I ran into this problem: the resulting picture is always bigger than the original and a bit blurry.
Here's what I used (in Scala):
No, my code is exactly the same, it's just in Scala (I also tried running the Java version, the same result)
import javafx.application.Application
import javafx.scene.Scene
import javafx.scene.image.ImageView
import javafx.scene.input.Clipboard
import javafx.scene.layout.StackPane
import javafx.stage.Stage
object Test extends App{
Application.launch(classOf[HelloWorld], args: _*)
}
class HelloWorld extends Application {
override def start(primaryStage: Stage) {
primaryStage.setTitle("Hello World!")
val root = new StackPane
val image = Clipboard.getSystemClipboard().getImage()
val imageView = new ImageView(image)
root.getChildren.add(imageView)
primaryStage.setScene(new Scene(root, 300, 250))
primaryStage.show
}
}
Original picture and what ImageView makes of it:
http://imgur.com/AFJudkL
I've also tried saving the image to a file and it's still distorted, so the problem is not in ImageView.
Even had a wild idea to call SetProcessDPIAware from WinAPI, had absolutely no effect.
Is there any way to show the image without distortions?
Thanks!
UPDATE: I've provided the full version of the code (It's exactly the same as the Java version below. I'm running it on Windows 10, jdk1.8.0_131, DPI is set to 175%.
I'm more and more certain that the problem I'm having is because of DPI - the image ImageView is showing is exactly 1.75 times larger that the original. Now I can force it to be of the right size with the following trick:
imageView.setFitHeight(image.getHeight/1.75)
imageView.setFitWidth(image.getWidth/1.75)
But it's still blurry. Also I found a great blog post that deals with that problem (different aspect of it, though - snapshot taking). However, I have no idea how to apply this solution to my conundrum.
http://news.kynosarges.org/2017/02/01/javafx-snapshot-scaling/
You should try to set the preserveRatio property of the image view.
https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/ImageView.html#preserveRatioProperty
Update:
I converted your code fragment into an executable example and when I run this on my Mac (Retina) I don't see any distortion at all. So, how is your code (which you didn't provide) different from mine and what are the relevant characteristics of your Windows box?
public class ClipboardBug extends Application {
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Hello World!");
StackPane root = new StackPane();
Image image = Clipboard.getSystemClipboard().getImage();
ImageView imageView = new ImageView(image);
imageView.setPreserveRatio(true);
root.getChildren().add(imageView);
primaryStage.setScene(new Scene(root));
primaryStage.sizeToScene();
primaryStage.show();
}
}
In my JavaFX application I use a TreeView. The single TreeItems contain an image. Unfortunately, the image is shown only once.
The code for loading the image looks like the following. It is called every time the TreeView changes. The Images are cached in a Map ("icons"). Thus, a new ImageView is created every time.
public final ImageView getImage(final String imageConstant) {
final Image img;
if (icons.containsKey(imageConstant)) {
img = icons.get(imageConstant);
}
else {
if (isRunFromJAR) {
img = new Image("/path/" + imageConstant, iconSizeWidth,
iconSizeHeight, false, false);
}
else {
img = new Image(getClass().getResourceAsStream(imageConstant), iconSizeWidth,
iconSizeHeight, false, false);
}
icons.put(imageConstant, img);
}
return new ImageView(img);
In the updateItem method of my TreeCells, the ImageView returned above is stored into a field called icon. The field is used in the following code, also from updateItem:
if (icon == null) {
setGraphic(label);
}
else {
final HBox hbox = new HBox(ICON_SPACING);
final Label iconLabel = new Label("", icon);
hbox.getChildren().addAll(iconLabel, label);
setGraphic(hbox);
}
But for some reason, the problem shown in the gif occurs.
Update
Actually, the ImageViews were cached internally, which led to de-duplication. Using multiple ImageViews is the solution.
the ImageView returned above is stored into a field called icon.The field is used in the following code...
The ImageView is type of Node. A Node can only have one parent at a time!
So don't store/cache a ImageView(-Node). Create new ImageView-Nodes.
Edit:
As pointed out in the comments by James_D:
...you can use the same Image(-Object) for every ImageView...
I was trying to display a picture in a box with JavaFX. I followed methods documented on Oracle, but it still did not work, though it was extremely similar to the example shown on Oracle. My code is here:
public class TesterJavaFX extends Application {
#Override
public void start(Stage primaryStage) {
Image img = new Image("character.png");
ImageView imgview = new ImageView();
imgview.setImage(img);
imgview.setFitWidth(100);
imgview.setPreserveRatio(true);
imgview.setSmooth(true);
imgview.setCache(true);
HBox box = new HBox();
box.getChildren().add(imgview);
StackPane root = new StackPane();
root.getChildren().add(box);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
I have a file called rocket.png in the "src" directory. It even shows up on the IDE. But Java causes a illegal argument exception, and i don't know why. Can anybody help me? Thanks.
Note: The imports are all present.
The string passed to the Image constructor is a URL. If the image file is in the root of your classpath, the following should work:
Image img = new Image(getClass().getResource("/character.png").toExternalForm());
I have a little problem/question...
I want to hide one sprite and show another one but eclipse gives me error "The local ... may not have been inatialized". Unfortunatelly I don't have another idea to hide and show those sprites...
Can anybody help me?
Code:
protected Scene onCreateScene() {
final Scene scene = new Scene();
Sprite backgroundSprite = new Sprite(0, 0, this.mBackgroundTextureRegion, getVertexBufferObjectManager());
scene.attachChild(backgroundSprite);
final Katapulta S_katapulta_wystrzelona = new Katapulta(10, 300, this.mKatapulta_wystrzelona, getVertexBufferObjectManager());
final Katapulta S_katapulta_zaladowana = new Katapulta(10, 300, this.mKatapulta_zaladowana, getVertexBufferObjectManager()){
#Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY) {
// IN THIS LINE I HAVE ERROR S_katapulta_zaladowana.setVisible(false);
S_katapulta_wystrzelona.setVisible(true);
return true;
}
};
scene.attachChild(S_katapulta_zaladowana);
scene.attachChild(S_katapulta_wystrzelona);
S_katapulta_wystrzelona.setVisible(false);
scene.registerTouchArea(S_katapulta_zaladowana);
return scene;
}
Just use setVisible(false); instead of S_katapulta_zaladowana.setVisible(false); Because of the way you used the onAreaTouched() method.
Try adding this.
setOnSceneTouchListener(this);
Try by setting tag to all sprites .Then call the sprite using tag and then make it Invisible
You have to initialize the variable so that it is actually pointing to something it can use
ie;
int x = new int;
x = 69;