i am having some trouble including images in my JavaFX project. The project stores the resources in the src/main/resources folder and it houses the FXML documents and all the images. The FXML documents load just fine, but the image locations all show null.
My code is as follows...
package VennDiagram;
import java.io.File;
import javax.imageio.ImageIO;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
public class View extends Application{
public static Stage primaryStage;
public static Scene promptWindow;
public static Scene refactor;
public static Scene scene;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception{
System.out.println(getClass().getResource("/views/View.fxml"));
System.out.println(getClass().getResource("/views/openingPage.fxml"));
System.out.println(getClass().getClassLoader().getResource("/views/openingPage.css"));
primaryStage = stage;
System.out.println(getClass().getResourceAsStream("/views/newFileButton.png"));
Parent root = FXMLLoader.load(getClass().getResource("/views/View.fxml"));
Parent root2 = FXMLLoader.load(getClass().getResource("/views/openingPage.fxml"));
scene = new Scene(root);
promptWindow = new Scene(root2,1020,580);
primaryStage.setOnCloseRequest(event ->{
quitProgramAlert.display("Confirm Exit", "Are you sure you want to exit?");
if(!quitProgramAlert.closePressed) {
event.consume();
}
});
primaryStage.setMinHeight(600);
primaryStage.setMinWidth(750);
primaryStage.setTitle("VennDiagram Creator");
primaryStage.setScene(promptWindow);
primaryStage.setResizable(false);
primaryStage.show();
}
}
It gives me an error saying the resource cannot be found.
Additional Details:
The project is built using gradle. I load my FXML files in using the same method as i do for the images.
It works just fine with the the FXML documents.
EDIT: The project structure is shown below...
Related
I found this piece of code, but it won't run a new blank window and keep getting NullPointerException error. p.s. I'm new to programming. Any help would be appreciated thanks.
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
BorderPane root = new BorderPane();
try {
Scene scene = new Scene(root,640,480);
scene.getStylesheets().add(getClass().getResource("/application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
root.setCenter(new RootLayout());
}
public static void main(String[] args) {
launch(args);
}
}
I had the same common problem when I started with JavaFX but I can explain It,
It throws null pointer exception because it is not able to find your CSS file from the specified location.
I've found that you are getting nullpointer exception at the below line,
scene.getStylesheets().add(getClass().getResource("/application.css").toExternalForm());
There is also another way to add your CSS file to scene
1) scene.getStylesheets().add("application.css");
2) scene.getStylesheets().add(this.getClass().getResource("/application.css").toString());
3) Package should be inside src directory and css also should be in src directory.
scene.getStylesheets().add(<packageName>.<ClassName>.class.getResource("/application.css").toExternalForm());
I'm using OpenJDK11.
I have two Java files in the current folder, that are supposed to run together to be a JavaFX application.
One of them is called Main.java and runs the main window. Another is Alert.java, and is supposed to run an alternate window which is an alert type.
Now, I ran the following command:
javac -cp "c:\projects\java\currentProject" --module-path "c:\Program Files\Java\javafx-sdk-11.0.1\lib" --add-modules=javafx.controls,javafx.fxml Alert.java Main.java
While Alert.java compiled just fine, Main.java could not import the Alert class and gave an error on "import Alert". I tried "import Alert.Alert" and "import currentProject.Alert" but still, it didn't work.
Also, I declared package "package currentProject" at the start of each file and it still gave an error.
What am I supposed to do to get it running? I already failed on installing JavaFX on all available IDEs, so I'm not going to use an IDE other than Atom. But how do I compile it properly?
more info -
file structure:
c->projects->java->economicManager->( Alert.java ,Main.java, financialManager.fxml, alert.fxml, Alert.class, Alert$Controller.class, Main.class [previously compiled version])
Alert.java:
package financialManager;
import javafx.stage.Stage;
import javafx.stage.Modality;
import javafx.scene.Scene;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import java.util.Map;
public class Alert {
public Stage stage;
private Controler_Class controler;
public Alert(Parent root) {
Controler_Class clas = new Controler_Class(root);
this.controler = clas;
Scene scene = new Scene(root);
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle("financial report");
stage.setScene(scene);
this.stage = stage;
stage.showAndWait();
}
private class Controler_Class{
Parent root;
public Controler_Class(Parent root){
}
}
}
Main.java:
package financialManager;
import Alert;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.Parent;
import javafx.scene.control.ListView;
import javafx.scene.control.SplitPane;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import java.util.Map;
public class Main extends Application{
#Override
public void start(Stage stage) throws Exception{
final int width = 300;
final int height = 450;
stage.setTitle("hello mofos");
FXMLLoader loader = new FXMLLoader(getClass().getResource("financialManager.fxml"));
Parent root = loader.load();
Scene scene = new Scene(root, width, height);
Map<String, Object> mapper = loader.getNamespace();
AnchorPane pane = (AnchorPane) mapper.get("splitpane1_anchorpane");
if(pane != null)
SplitPane.setResizableWithParent(pane, false);
else
System.out.println("it's null you idiot!");
Button btn = (Button) mapper.get("economicReport");
btn.setOnMouseClicked((event) -> {
FXMLLoader loader2 = new FXMLLoader(getClass().getResource("alert.fxml"));
Parent parent = loader2.load();
Alert alert = new Alert(parent);
});
/*
ChangeListener<Number> stageSizeListener = (observable, oldValue, newValue) ->
pane.setDividerPositions(0.20219435736677116);
stage.widthProperty().addListener(stageSizeListener);
stage.heightProperty().addListener(stageSizeListener);
*/
stage.setScene(scene);
stage.show();
}
public static void main(String[] args){
launch();
}
}
I see that you are importing the Alert class wrongly. Your package is financialManager, so you should use it in the import line like this:
import financialManager.Alert;
About your issues with IDEs, I made JavaFX work fine with Eclipse and IntelliJ on OpenJDK 11 without any issues a few days ago - For OpenJDK you will need OpenJFX, and if you are interesting in some reading, this is the link from Oracle's blog on their plans for JavaFX.
Good luck!
Currently, I am trying to create a timer that displays in the corner of your screen. I want it to show even if there is currently a full-screened application running. Currently I've tried Stage#setAlwaysOnTop(true), however that only functions for normal applications, not when they are full-screened.
package sample;
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 stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
stage.setTitle("Timer");
stage.setScene(new Scene(root, 300, 275));
stage.setAlwaysOnTop(true);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
This is the standard JavaFX example with IntelliJ, however with the one modification which was Stage#setAlwaysOnTop(true). How would I get this to function ontop of the full-screen, or at least stay omnipresent no matter the application.
I am trying to create a program to teach people about GNU/Linux and the command line, I have my main.java
package sample;
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 {
Stage window;
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
window = primaryStage;
Parent root = FXMLLoader.load(getClass().getResource("login.fxml"));
primaryStage.setTitle("Learnix");
primaryStage.setScene(new Scene(root, 800, 500));
primaryStage.show();
}
}
And the controller to go with it.
package sample;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import java.io.IOException;
public class loginController {
public Button loginBtn;
public void loginBtnClick() throws IOException {
System.out.println("You are logged in");
}
}
I have tried things such as:
FXMLLoader.load(getClass().getResource("lessons.fxml"));
But I can't figure out how to get it to swap scenes. I have seen many tutorials on YouTube and it Stack Overflow but many of them have all of the JavaFX on the main.java and not in separate files as I am using scenebuilder.
Thank you.
You can either call Stage.setScene() to change the whole scene or just substitute a root to the new one by Scene.setRoot():
Parent newRoot = FXMLLoader.load(getClass().getResource("lessons.fxml"));
primaryStage.getScene().setRoot(newRoot);
I want my java application such that if user chooses to click on a button the PDF opens using the default PDF reader that is installed in the computer.
The PDF which i want to be opened is present in same package "application".
The code which I am using is
package application;
import java.io.File;
import javafx.application.Application;
import javafx.application.HostServices;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(final Stage primaryStage) {
Button btn = new Button();
btn.setText("Load PDF");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
File pdfFile = new File("computer_graphics_tutorial.pdf");
getHostServices().showDocument(pdfFile.toURI().toString());
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
If the PDF file is in the same package as the caller file (as you state), then
getHostServices().showDocument(getClass()
.getResource("computer_graphics_tutorial.pdf").toString());
should solve the problem.
The getResource method can be used really flexibly to locate files. Here is a small description how to use it: JavaFX resource handling: Load HTML files in WebView.