Images showing in scene builder, but not after compilation - java

I just want to display an image but no matter whati've tried, it's not showing up.
I opened up a new project from a default template to see if I had done something, but it won't work either.
It will show in the scene builder, but once i compile, nothing there.
Main:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
#Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 400, 600);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
and the fxml file being:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ImageView fitHeight="325.0" fitWidth="347.0" layoutX="138.0" layoutY="38.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="#../../../Images/471962_nemuli_catstronaut.png" />
</image>
</ImageView>
</children>
</AnchorPane>
Any clue what's happening? I am running on linux if that means anything.
file tree

Related

JavaFX Stage shows always empty scene

Using:
IntelliJ IDEA community ide.
Java JDK 9.0.1
Scene builder 9.0.1
I always get empty scene.
Here is the fxml file code:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.GridPane?>
<GridPane alignment="center" hgap="10" vgap="10" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/9.0.1" fx:controller="view.Controller">
<children>
<Button mnemonicParsing="false" text="Button" />
</children>
</GridPane>
Here is the main class code:
package view;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 600, 400));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Changing sceenes with IntelliJ 2018.1 and Scene Builder 9.0.1

I have created a new JavaFx project.
In the project I have a Main class, a Controller class and a design file.
When I click on "New products" I want to load a new fxml file named new_product.fxml.
However I get a error when I click the "New product" button:
Caused by: java.lang.NullPointerException
at sample.Main.changeScene(Main.java:33)
at sample.Controller.buttonNewProductOnMouseClicked(Controller.java:21)
In Main.java line 33 is the primaryStage. Looks like my controller can't access it?
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class Main extends Application {
Stage primaryStage;
#Override
public void start(Stage primaryStage) throws Exception{
this.primaryStage = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
Scene primaryScene = new Scene(root, 300, 275);
primaryStage.setScene(primaryScene);
primaryStage.show();
}
public void changeScene(String fxml){
Parent pane = null;
try {
pane = FXMLLoader.load(getClass().getResource(fxml));
} catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene( pane );
primaryStage.setScene(scene);
}
public static void main(String[] args) {
launch(args);
}
}
My design file
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<BorderPane xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<top>
<HBox prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="buttonProducts" mnemonicParsing="false" onMouseClicked="#buttonProductsOnMouseClicked" text="Products" />
<Button fx:id="buttonNewProduct" mnemonicParsing="false" onMouseClicked="#buttonNewProductOnMouseClicked" text="New products">
<HBox.margin>
<Insets left="5.0" />
</HBox.margin></Button>
</children>
</HBox>
</top>
<center>
<Label text="Label" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
The Controller class for the design file
package sample;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
public class Controller {
#FXML
private Button buttonProducts;
#FXML
private Button buttonNewProduct;
public void buttonProductsOnMouseClicked(javafx.scene.input.MouseEvent mouseEvent) {
buttonProducts.setText("You have clicked on me!");
}
public void buttonNewProductOnMouseClicked(javafx.scene.input.MouseEvent mouseEvent) {
buttonNewProduct.setText("You have clicked on me!");
Main mainclass = new Main();
mainclass.changeScene("new_product/new_product.fxml");
}
}

Creating a large body of text with different styles - JavaFX FXML

In the fxml class of my JavaFx application I want to add a large body of text using minimal components (instead of adding multiple labels per line). I would also like to create varying styles of text in the same component. What component should I use (e.g TextArea) and how would I go about create multiple styles inside it (using css).
Use a TextFlow and add Text to it. You can style individual Text component with different style using css on them.
Complete example :
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;
public class TextFlowExample extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
Text text1 = new Text("First Text\n");
text1.setStyle("-fx-font-size: 20; -fx-fill: darkred;");
Text text2 = new Text("\nSecond Text");
text2.setStyle("-fx-font-size: 30; -fx-fill: goldenrod;");
TextFlow textFlow = new TextFlow(text1, text2);
primaryStage.setScene(new Scene(textFlow, 200, 200));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Output
Equivalent FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import java.lang.*?>
<?import javafx.scene.text.*?>
<TextFlow lineSpacing="10.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" textAlignment="CENTER" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Text strokeType="OUTSIDE" strokeWidth="0.0" style="-fx-font-size: 20; -fx-fill: darkred;" text="
First Text" />
<Text strokeType="OUTSIDE" strokeWidth="0.0" style="-fx-font-size: 30; -fx-fill: goldenrod;" text="
Second Text" />
</children>
</TextFlow>

JavaFX TextField Get Clicked Item

I'm trying to load(WebEngine) links that are in a TextArea when you click on them. But I have no idea how to get the clicked item.
This is something i tried:
area.setOnMouseClicked(event -> {
WebController.getEngine().load((String) event.getSource());
});
event.getSource() will be the TextArea in your case.
So your code would either be
area.setOnMouseClicked(event -> WebController.getEngine().load(((TextArea) event.getSource()).getText()));
or simpler:
area.setOnMouseClicked(event -> WebController.getEngine().load(area.getText()));
Edit - Simple TextFlow example:
#Override
public void start(Stage primaryStage) {
TextFlow textFlow = new TextFlow();
textFlow.setOnMouseClicked(ev -> {
if(ev.getTarget() instanceof Text) {
Text clicked = (Text) ev.getTarget();
System.out.println(clicked);
}
});
IntStream.range(0, 500).mapToObj(Integer::toString).map(Text::new).forEach(textFlow.getChildren()::add);
BorderPane borderpane = new BorderPane(textFlow);
borderpane.setPadding(new Insets(20));
Scene scene = new Scene(borderpane, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
If anyone wanna see what it turned out here is my code im using:
package com.ekko.history;
import java.net.URL;
import java.util.Objects;
import java.util.ResourceBundle;
import com.ekko.WebController;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
public class HistoryController implements Initializable {
#FXML
private TextFlow textFlow;
#Override
public void initialize(URL location, ResourceBundle resources) {
textFlow.getChildren().clear();
textFlow.setOnMouseClicked(ev -> {
if(ev.getTarget() instanceof Text) {
Text clicked = (Text) ev.getTarget();
WebController.getEngine().load(clicked.getText());
}
});
HistoryClient.getHistory().stream().filter(Objects::nonNull).forEach(s -> {
Text text = new Text(s + "\n");
textFlow.getChildren().add(text);
});
HistoryClient.getHistory().clear();
}
}
And this is the FXML file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<ScrollPane 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="com.ekko.history.HistoryController">
<content>
<TextFlow fx:id="textFlow" prefHeight="400.0" prefWidth="600.0" />
</content>
</ScrollPane>
Thanks to eckig for helping me!

How do you add nodes to an object that is not the main parent (javafx)?

I could not find anything on the topic anywhere i looked. I would like to add a rectangle to my AnchorPane (anchorPaneOne) that is inside my ScrollPane (scrollPane) but whatever i see to do i keep getting errors.
Here is my code:
Main Class:
package application;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Main extends Application {
#FXML
ScrollPane scrollPane;
#FXML
AnchorPane main;
#FXML
AnchorPane anchorPaneOne;
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("/fxml/Main.fxml"));
Scene scene = new Scene(root,600,400);
primaryStage.setScene(scene);
primaryStage.setTitle("Stack Overflow Example");
primaryStage.show();
Rectangle r = new Rectangle();
//It will not let me do anchorPaneOne.getChildren().add(r);
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Main.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<AnchorPane fx:id="main" 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">
<children>
<ScrollPane fx:id="scrollPane" prefHeight="400.0" prefWidth="600.0">
<content>
<AnchorPane fx:id="anchorPaneOne" minHeight="0.0" minWidth="0.0" prefHeight="800.0" prefWidth="585.0" />
</content>
</ScrollPane>
</children>
</AnchorPane>
Any assistance would be appreciated.
Thanks
The loader needs to know where to inject the instances to - without the field anchorPaneOne can't be instantiated and remains null. That's done by the controller property which must be set before actually loading the ui:
// create a loader
FXMLLoader loader = new FXMLLoader(getClass().getResource(resource));
// set this instance as its controller
loader.setController(this);
// load the ui
Parent root = loader.load();
Scene scene = new Scene(root, 600, 400);
primaryStage.setScene(scene);
primaryStage.setTitle("Stack Overflow Example");
primaryStage.show();
Rectangle r = new Rectangle(100, 100);
// now the field is instantiated and can be accessed without NPE
anchorPaneOne.getChildren().add(r);

Categories