Why cant i add images to my JavaFX Project? [duplicate] - java

This question already has an answer here:
How do I determine the correct path for FXML files, CSS files, Images, and other resources needed by my JavaFX Application?
(1 answer)
Closed 11 months ago.
I get the same error again and again when i try to add images to my JavaFX.
Error: at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
(more lines follow).
It must be related to the path to the images that I specified. I have already read through the general "path" tutorial on StackOverflow without success.
I just want to make a simple scrollBar which enables scrolling through some Images i added to a VBox.
Heres my directory:
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.effect.DropShadow;
import javafx.scene.effect.Shadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class Scrollbar3 extends Application {
// Variablen
final ScrollBar scrollbar = new ScrollBar();
final String[] images = {
"Bilder/bild0.jpg", // 0
"Bilder/bild1.jpg",
"Bilder/bild2.jpg",
"Bilder/bild3.jpg",
"Bilder/bild4.jpg",
};
DropShadow shadow = new DropShadow();
final VBox vbox = new VBox();
#Override
public void start(Stage primaryStage) throws Exception {
// Scene / root
Group root = new Group();
Scene scene = new Scene(root, 400, 400);
root.getChildren().addAll(vbox, scrollbar);
// Effekt
shadow.setColor(Color.BLACK);
shadow.setOffsetX(10);
shadow.setOffsetY(10);
// VBox
vbox.setLayoutX(5);
vbox.setSpacing(10);
vbox.setPadding(new Insets(20));
// Scrollbar
scrollbar.setLayoutX(scene.getWidth() - scrollbar.getWidth());
scrollbar.setOrientation(Orientation.VERTICAL);
scrollbar.setPrefHeight(400);
scrollbar.setMax(2000);
// Bilder
for(int i = 0; i < images.length; i++) {
final ImageView imageView = new ImageView(new Image(images[i]));
imageView.setEffect(shadow);
vbox.getChildren().add(imageView);
}
// Eventhanlding / Listener
scrollbar.valueProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, Number newValue) {
vbox.setLayoutY(-newValue.doubleValue());
}
});
// Stage
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

It looks like you are treating your images as resource images because they are contained in the source folder.
Change the line with the image creation to
final ImageView imageView = new ImageView(new Image(this.getClass().getResourceAsStream(images[i])));
and add an "/" in front of your image paths.

Related

No image appearing on pane, how to fix this?

I wrote this java application on NetBeans IDE 8.2 to show an image stored on my local directory in the same directory of the classes files directory (as stated in the documentation), but when running there is no image appearing on the scene although there is no exception,, anyone has any idea how to fix this??
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.layout.HBox;
import javafx.geometry.Insets;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.geometry.Insets;
import java.io.File;
public class ShowImage extends Application{
#Override
public void start(Stage primaryStage) {
Pane pane = new HBox();
pane.setPadding(new Insets(5, 5, 5, 5));
Image image = new Image("image.jpg");
pane.getChildren().add(new ImageView(image));
ImageView imageView2 = new ImageView(image);
imageView2.setFitHeight(100);
imageView2.setFitWidth(100);
pane.getChildren().add(imageView2);
ImageView imageView3 = new ImageView(image);
imageView3.setRotate(90);
pane.getChildren().add(imageView3);
Scene scene = new Scene(pane, 300, 300);
primaryStage.setTitle("Show Image");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
The final solution to this repeated problem is to create a new sub packadge from NetBeans under your packadge, name it "resources" for example and and put the your image in the directory of the sub package and edit the path in the code as this
Image image = new Image("resources/image.jpg");
this will avoid the path issues, and route the file from package directly.

How to use both JavaFX Scene Builder while still have the choice to design root with code?

I wanted to give SceneBuilder a try because its pain to center objects manually (in code). Unfortunately root is taken from me when I use FXML, so I can't set group as root. What I want to do is to operate on canvas (that is added to root group) while still having SceneBuilder FXML file working.
For example when Ive set root sceneBuilder FXML file then i couldnt add sprites to it in code. Vice versa when I have set root as group then the application wasnt making use of FXML file.
How to connect these? Below is code with use of group as root. I have added sprite, which is not visible in SceneBuilder. Also the button made in SceneBuilder is not visible after compiling the application.
Code:
package zegelardo;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.application.Application;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.Group;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.animation.AnimationTimer;
import javafx.event.EventHandler;
import javafx.scene.input.KeyEvent;
import javafx.scene.control.Button;
import java.util.ArrayList;
import java.util.Iterator;
public class Zegelardo extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Group rootx = new Group();
Scene scene = new Scene(rootx);
scene.setFill(Color.BLACK);
stage.setScene(scene);
stage.setTitle("Zegelardo");
Sprite tlo = new Sprite();
tlo.setImage("test55.gif");
tlo.setPosition(0, 0);
Canvas canvas = new Canvas( 800, 400 );
rootx.getChildren().add(canvas);
GraphicsContext gc = canvas.getGraphicsContext2D();
// gc.clearRect(0, 0, 1000,800);
// briefcase.render( gc );
tlo.render(gc);
// Group leaf = new Group();
// root.getChildren().add(canvas);
// Canvas canvas = new Canvas( 800, 400 );
//leaf.getChildren().add( canvas );
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}

JavaFX 8 : ListView with Images and Label that autoscales/autoresizes

I want to have an horizontal ListView which each ListCell contains an Image with a Label under it.
Apart from that the ListView will be on a GridPane so it's size can change.Knowing that I want each cell and it's content, in this case the image, to fill all the height.If the ListView changes size, the image and label should resize to fit on the new ListView size.
Right now it shows like this, if the image is smaller than the listView:
smallerImage
And if the image is bigger than the ListView it looks like this:
biggerImage
The problem with this is that it doesn't resize the image to fit the available Height.
Here is the code from the screenshots examples. It uses images from placeholdit:
package com.example;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;
import java.util.ArrayList;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
ObservableList<Image> imagesObservableList = FXCollections.observableList(new ArrayList<>());
for (int i = 0; i<10;i++) {
// Adding 10 images
//Bigger one
// Image image = new Image("https://placeholdit.imgix.net/~text?txtsize=14&txt=150%C3%97300&w=150&h=300");
//Smaller one
Image image = new Image("https://placeholdit.imgix.net/~text?txtsize=14&txt=50%C3%97150&w=50&h=150");
// Image image = new Image(getClass().getClassLoader().getResource("image_50x150.png").toString());
imagesObservableList.add(image);
}
ListView<Image> listView = new ListView<>(imagesObservableList);
listView.setOrientation(Orientation.HORIZONTAL);
listView.setCellFactory(new Callback<ListView<Image>, ListCell<Image>>() {
#Override
public ListCell<Image> call(ListView<Image> imageViewListView) {
return new ListCell<Image>() {
ImageView imageView;
Label title;
VBox vBox;
{
vBox = new VBox();
vBox.setAlignment(Pos.CENTER);
imageView = new ImageView();
imageView.setPreserveRatio(true);
title = new Label("Title");
title.setAlignment(Pos.TOP_CENTER);
vBox.getChildren().addAll(imageView,title);
vBox.setFillWidth(false);
setGraphic(vBox);
}
#Override
protected void updateItem(Image image, boolean bln) {
super.updateItem(image, bln);
imageView.setImage(image);
}
};
}
});
GridPane pane = new GridPane();
pane.addRow(0);
pane.addRow(1, listView);
pane.addRow(2);
pane.addColumn(0);
RowConstraints topBottomConstraint = new RowConstraints();
topBottomConstraint.setPercentHeight(30);
RowConstraints centerConstraint = new RowConstraints();
centerConstraint.setPercentHeight(30);
pane.getRowConstraints().add(topBottomConstraint);
pane.getRowConstraints().add(centerConstraint);
pane.getRowConstraints().add(topBottomConstraint);
ColumnConstraints columnConstraints = new ColumnConstraints();
columnConstraints.setPercentWidth(100);
pane.getColumnConstraints().add(columnConstraints);
primaryStage.setScene(new Scene(pane));
primaryStage.show();
}
}
I guess the idea would be to bind the imageView.fitHeightProperty() to something. But I'm clueless what to bind. I tried binding it to the cell height and substract the "title" height like this:
ImageView.fitHeightProperty().bind(heightProperty().subtract(title.heightProperty()));
But it doesn't work as I expected and it shows weird until I scroll.

How to make a Button on a JavaFX's browser?

I'm trying to make a "launcher" with javafx.
This is my code :
I'm not shure you have to read all of this code, this code is here.
I'm trying to put a javaFX "play" button (i know how to make a button and how to set up an onclick event but i don't know where to add it :/)
Have you got an idea ? Thx.
package fr.whiteplay.main.launcher;
public class Launcher{
private static WebViewSample launcher;
private static String[] a;
public static void main(String[] args){
launcher = new WebViewSample();
a = args;
}
public static void start(){
launcher.go(a);
}
}
package fr.whiteplay.main.launcher;
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
public class WebViewSample extends Application{
private Browser browser;
private Scene scene;
public void start(Stage stage){
// create the scene
stage.setTitle("WhitePlay");
browser = new Browser();
scene = new Scene(browser, 992, 620, Color.web("#000000"));
stage.setScene(scene);
stage.show();
}
public static void go(String[] args){
launch(args);
}
}
package fr.whiteplay.main.launcher;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
class Browser extends Region{
final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
public Browser(){
getStyleClass().add("browser");
webEngine.load("http://www.whiteplay.fr/launcher/index.html");
getChildren().add(browser);
}
private Node createSpacer(){
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
return spacer;
}
protected void layoutChildren(){
layoutInArea(browser, 0, 0, getWidth(), getHeight(), 0, HPos.CENTER, VPos.CENTER);
}
}
Instead of the browser itself, the scene root must be a structured panel, which contains the browser, the button, and whatever else.
The simplest example is to replace your WebViewSample.start() method with the following:
public void start(Stage stage){
// create the scene
stage.setTitle("WhitePlay");
browser = new Browser();
BorderPane root = new BorderPane();
root.setCenter(browser);
Button button = new Button("Play");
root.setBottom(button);
button.setOnAction(a -> System.out.println("Play"));
scene = new Scene(root, 992, 620, Color.web("#000000"));
stage.setScene(scene);
stage.show();
}
Check this page for further reference on various layouts options, and how to work with them.

Oracles JavaFX example with mouse click position label wrong?

At http://docs.oracle.com/javafx/2/charts/pie-chart.htm Oracle suggests using
caption.setTranslateX(e.getSceneX());
caption.setTranslateY(e.getSceneY());
to place a Label where the mouse was clicked.. But this does not work at all. See this print screen for proof:
In the code for the example you cite, the PieChart and caption Label are both placed directly in a Group which is the root of the scene. The position of the Label before applying transformations is therefore (0,0) (the top left of the Scene), and so translating it by (e.getSceneX(), e.getSceneY()) moves it to the position of the mouse.
If your layout is different, then the same computation will not necessarily work. For a more general solution, put the chart and caption in a Group, and then call sceneToLocal(...) on the Group to translate the scene coordinates to the correct coordinates in the Group:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class PieChartSample extends Application {
#Override
public void start(Stage stage) {
BorderPane root = new BorderPane();
ObservableList<PieChart.Data> pieChartData =
FXCollections.observableArrayList(
new PieChart.Data("Grapefruit", 13),
new PieChart.Data("Oranges", 25),
new PieChart.Data("Plums", 10),
new PieChart.Data("Pears", 22),
new PieChart.Data("Apples", 30));
final PieChart chart = new PieChart(pieChartData);
chart.setTitle("Imported Fruits");
final Label caption = new Label("");
caption.setTextFill(Color.DARKORANGE);
caption.setStyle("-fx-font: 24 arial;");
Group chartWithCaption = new Group(chart, caption);
for (final PieChart.Data data : chart.getData()) {
data.getNode().addEventHandler(MouseEvent.MOUSE_PRESSED,
new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent e) {
Point2D locationInScene = new Point2D(e.getSceneX(), e.getSceneY());
Point2D locationInParent = chartWithCaption.sceneToLocal(locationInScene);
caption.relocate(locationInParent.getX(), locationInParent.getY());
caption.setText(String.valueOf(data.getPieValue()) + "%");
}
});
}
root.setCenter(chartWithCaption);
// Just some stuff to change the overall layout:
HBox controls = new HBox(5);
controls.setPadding(new Insets(10));
controls.setAlignment(Pos.CENTER);
controls.getChildren().addAll(new Label("Some other stuff here"), new TextField(), new Button("OK"));
root.setTop(controls);
root.setPadding(new Insets(0, 0, 10, 40));
root.setLeft(new Circle(25, Color.SALMON));
Scene scene = new Scene(root);
stage.setTitle("Imported Fruits");
stage.setWidth(600);
stage.setHeight(500);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Categories

Resources