So, I'm getting a StackOverflowError (Unwrapped from a InvocationTargetException), and I can't for the life of me figure out why.
package gui;
import errorhandling.ErrorLogBook;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class GUIRouter extends Application{
public static void main(String[] args)
{
try
{
Application.launch(GUIRouter.class, (String[])null);
}
catch (Exception e)
{
System.out.println(e.getCause().toString());
}
}
#Override
public void start (Stage primaryStage)
{
try
{
StackPane page = (StackPane) FXMLLoader.load(GUIRouter.class.getResource("LoginScreen.fxml"));
Scene scene = new Scene(page);
primaryStage.setScene(scene);
primaryStage.show();
}
catch (Exception e)
{
ErrorLogBook.logReport(e);
}
}
It fails at the first try block with:
Application.launch(GUIRouter.class, (String[])null);
This is a FXML application that I'm building with NetBeans and JavaFX Scene Builder 2.0
Any ideas about why my code keeps crashing?
My guess would be that your .fxml in "LoginScreen.fxml" has GuiRouter defined as its controller, which it then creates through reflection. My guess is that during that creation it ends up calling start(..) creating a loop.
Try this:
package gui;
import errorhandling.ErrorLogBook;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class GUIRouter extends Application{
public static void main(String[] args)
{
launch(args);
}
#Override
public void start (Stage primaryStage)
{
try
{
StackPane page = FXMLLoader.load(getClass().getResource("/gui/LoginScreen.fxml"));
Scene scene = new Scene(page);
primaryStage.setScene(scene);
primaryStage.show();
}
catch (Exception e)
{
e.printStackTrace();
ErrorLogBook.logReport(e);
}
}
Without having the .fxml file and/or the stack trace, I (see no way but to ) guess the main cause of the exception in exactly the same way as Kiskae did.
However, why you do not replace the line
Application.launch(GUIRouter.class, (String[])null);
with the more simpler form
Application.launch(args);
Or at least
Application.launch(args, new String[0]);
To see if the exception still remains.
Thanks for all the responses!
However, after playing around with it, I have found the root of the problem.
I replaced
StackPane page = (StackPane) FXMLLoader.load(GUIRouter.class.getResource("LoginScreen.fxml"));
with
Parent root = FXMLLoader.load(getClass().getResource("LoginScreen.fxml"));
and now it's working just fine.
Related
I got scene first.fxml with firstController, it is BorderPane with one button(birthCert) in the left side.
When i click on button(birthCert) i succefully load second.fxml into center of BorderPane.
#FXML
void birthCert(ActionEvent event) {
Parent root;
try {
root = load(getClass().getResource("second.fxml"));
id_borderPane.setCenter(root);
} catch (IOException e) {
e.printStackTrace();
}
}
second.fxml is conected with secondController class and have 1 button(sendRequest). When this button is clicked i create instance of firstController and i want call method setscene to load third.fxml into center of borderPane.
third.fxml only show message "Your request was sent".
Problem is, when i call method setscene in class secondController with instance of firstController
c.setscene();
public void setscene() {
Parent root;
try {
root = load(getClass().getResource("third.fxml"));
id_borderPane.setCenter(root);
} catch (IOException e) {
e.printStackTrace();
}
}
it don't load third.fxml into center of BorderPane, nothing happens just second.fxml remains loaded.
I tried control printing and i tested if root is null but printing works fine and root is not null so i really don't understand what can cause that it doesn't show third.fxml in center of BorderPane
Here is the whole code:
package controllers;
import static javafx.fxml.FXMLLoader.load;
import java.io.IOException;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
public class firstController {
#FXML
private BorderPane id_borderPane;
#FXML
void birthCert(ActionEvent event) {
Parent root;
try {
root = load(getClass().getResource("second.fxml"));
id_borderPane.setCenter(root);
} catch (IOException e) {
e.printStackTrace();
}
}
public void setscene() {
Parent root;
try {
root = load(getClass().getResource("third.fxml"));
id_borderPane.setCenter(root);
} catch (IOException e) {
e.printStackTrace();
}
}
}
package controllers;
import java.io.IOException;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.control.TextArea;
import javafx.scene.input.MouseEvent;
public class secondController{
#FXML
void SendRequset(MouseEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("first.fxml"));
loader.load();
UserGUISendReqController c = loader.getController(); // instance of firstController
c.setscene();
}
}
Thank you a lot for help :)
You have:
FirstController
|- SecondController
Then in second controller you click the button to add third controller you're doing
FirstController
|- SecondController
|- new FirstController.setScene()
You should instantiate a new FirstController, you should either call up to SecondController parent, or pass the references to FirstController into second controller somehow.
You want to use either getParent on SecondController or some other method of passing the active FirstController into the SecondController so that when you call to it, it's the right one.
ps. People will also comment on your naming convention not following standards.
Context
I just started to learn JavaFX so I'm developing a program to discover it. The program I'm on needs a array, so I used ObservableList. But here is the problem, the items I add to the list are only accessible from the function itself.
Here is the situation :
package fr.cartes;
import fr.cartes.model.MapModel;
import fr.cartes.view.ListMapsController;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
import java.util.ArrayList;
public class MainApp extends Application {
private Stage primaryStage;
private ObservableList<MapModel> maps = FXCollections.observableArrayList();
public static void main(String[] args){
launch(args);
}
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("/!\\ Explorateur /!\\");
this.primaryStage.setAlwaysOnTop(true);
initializationOfProgram();
}
public void initializationOfProgram(){
initializeListMaps();
maps.add(new MapModel("Les Etats-Unis d'Amérique", "EU.jpg"));
maps.add(new MapModel("La France d'aujourdh'ui", "FR.jpg"));
for(MapModel mapModel : maps){
System.out.println(mapModel.getMapName());
}
}
public void initializeListMaps(){
for(MapModel map : maps){
System.out.println(map.getMapName());
}
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("view/ListMaps.fxml"));
Scene scene = new Scene(loader.load());
primaryStage.setScene(scene);
primaryStage.show();
ListMapsController controller = new ListMapsController();
controller.setMainApp(this);
controller.loadMapsOnListView(maps);
}catch(IOException exception){exception.printStackTrace();}
}
public ObservableList<MapModel> getMapsLists(){
return maps;
}
}
For example, if I put a println() test in the initializationOfProgram(), I will have "Les Etats-Unis d'Amérique" and "La France d'aujourd'hui" written on the console, but if I do this println() test in initializeListMaps(), it won't display anything.
Am I missing something obvious here ? Can you help me ?
Basically my code is like this:
fileOpener.setOnAction(
new EventHandler<ActionEvent>() {
#Override
public void handle(final ActionEvent e) {
myFileList.add(openMusicTracks.showOpenDialog(window));
System.out.println(myFileList.getName(0)); //prints file name so I know this works
}
});
I want the add method (that's inside of the EventHandler) to actually edit the arraylist for everywhere else so that later when I reference it in
ObservableList<String> playList = FXCollections.observableArrayList ();
for(int i = 0; i < myFileList.size(); i++) {
playList.add(i, myFileList.get(i).getName());
System.out.println(myFileList.getName(0)); //doesn't print the file name, so I know this doesn't work.
}
the arraylist won't be empty. How do I do this? I'm sorry if there's a more elegant way to word this, but I have honestly no idea how to research this, I've tried. Thanks.
A simple example which shows how can an ArrayList be shared between methods.
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.ArrayList;
import java.util.List;
public class Main extends Application {
private List<String> list = new ArrayList<>();
#Override
public void start(Stage primaryStage) {
Button add = new Button("Add");
Button display = new Button("Show");
// Add Items
add.setOnAction(event -> list.add("Item"));
// Display Items
display.setOnAction(e -> {
printAndClear();
});
VBox root = new VBox(10, add, display);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 200, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
private void printAndClear() {
list.forEach(System.out::println);
list.clear();
}
public static void main(String[] args) {
launch(args);
}
}
I am trying to terminate the thread that runs the JavaFX application when I close the window, without closing any other threads. This is my application class:
package testIt;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import java.io.IOException;
public class MemoryVisualizerApp extends Application{
public static void main(String[] args) {
launch(args);
}
//Setup the scene and launch with given properties
#Override
public void start(Stage primaryStage) throws IOException{
Parent root = FXMLLoader.load(getClass().getResource("/MemoryVisualizer.fxml"));
Scene scene = new Scene(root, 650, 340);
//Set whether the screen should be re-sizable (possibly best size = default)
primaryStage.setResizable(true);
primaryStage.setMinHeight(300);
primaryStage.setMinWidth(550);
primaryStage.setTitle("MINT Performance");
primaryStage.setScene(scene);
scene.getStylesheets().add("testIt/MemoryVisualizer.css");
primaryStage.show();
primaryStage.show();
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>()
{
public void handle(WindowEvent e){
System.out.println("test");
try {
stop();
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
}
}
For testing purposes, this app is the only thing running when I start the program, and so when I close the window, the entire program should terminate. But I still have the option to terminate the program (I'm using eclipse and the red square is still clickable), meaning the thread is still active.
How can I have it so that this thread terminates after closing the GUI window?
You can use Platform.exit() instead of stop()
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>()
{
public void handle(WindowEvent e){
System.out.println("test");
try {
Platform.exit();
}
catch (Exception e1) {
e1.printStackTrace();
}
}
});
Take a look at the JavaFX Application life cycle
Try overriding the stop() method:
#Override
public void stop(){
System.exit(0);
}
This will cause the application to stop running in the IDE.
HiEveryone,
I'm a beginner in Javafx and learning it to make app from someone tutorials, Now the problem is .. it's giving me an error as Expression expected? What's that mean ? Can anyone pls resolve my issue?..
Have a look into this SCREENSHOT.
here is my source codes:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.AnchorPane;
public class Main extends Application {
Stage primaryStage;
BorderPane rootLayout;
#Override
public void start(Stage primaryStage){
this.primaryStage=primaryStage;
primaryStage.setTitle("Address App");
initSample2Layout();
showSample();
}
public void initSample2Layout(){
try{
//here loading files from FXML..
FXMLLoader loader=new FXMLLoader();
loader.setLocation(Main.class.getResource("sample/Sample2.fxml"));
rootLayout=(BorderPane).loader.load();
Scene scene=new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
}catch(Exception e){e.printStackTrace();}
}
public void showSample(){
try{
//here we're loading files from FXML..
FXMLLoader loader2=new FXMLLoader();
loader2.setLocation(Main.class.getResource("sample/sample.fxml"));
AnchorPane ap=(AnchorPane).loader.load();
rootLayout.setCenter(ap);
}catch(Exception e){e.printStackTrace();}
}
public Stage getPrimaryStage(){
return primaryStage;
}
public static void main(String[] args) {
launch(args);
}
}
This is not valid syntax :
rootLayout=(BorderPane).loader.load();
If you want to cast to BorderPane, do :
rootLayout=(BorderPane)loader.load();
And the same goes for AnchorPane ap=(AnchorPane).loader.load();, which should be changes to AnchorPane ap=(AnchorPane)loader2.load();.
You have rootLayout=(BorderPane).loader.load(); with an extra . character before loader.
You probably want the following:
rootLayout=(BorderPane) loader.load();