This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
This is my Main Class
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("application/anwendung.fxml"));
primaryStage.setTitle("Benutzerverwaltung");
root.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(new Scene(root));
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
This is my Controller class
package application;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.input.InputEvent;
import javafx.stage.Stage;
class AnwendungsController {
#FXML
public Button closeButton;
#FXML
public void handleCloseButtonAction(ActionEvent event) {
Stage stage = (Stage) closeButton.getScene().getWindow();
stage.close();
}
}
And this is my fxml file
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="140.0" prefWidth="350.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.AnwendungsController">
<children>
<Button fx:id="closeButton" layoutX="18.0" layoutY="100.0" mnemonicParsing="false" onAction="#handleCloseButtonAction" onMouseClicked="#onMouseClickedCancelBtn" prefHeight="26.0" prefWidth="77.0" text="Abbrechen" />
<Label layoutX="10.0" layoutY="27.0" prefHeight="27.0" prefWidth="342.0" text="Sie können das System nun verwenden" textAlignment="CENTER" textOverrun="CLIP">
<font>
<Font name="System Bold" size="18.0" />
</font>
</Label>
</children>
</AnchorPane>
How can I fix it? I try everything from here JavaFX "Location is required." even though it is in the same package
UPDATE:
java.lang.NullPointerException: Location is required.
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3207)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at application.Main.start(Main.java:20)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Unknown Source)
Two problems exist:
1)The File path
2)The Controller was not set properly
Recommendation:
If you are using SceneBuilder, when you want to see what your controller might look like, you can go to View -> Show Sample Controller Skeleton.
Solution
Main class:
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
System.out.println(getClass().getResource("anwendung.fxml").getPath());
//other solution
//FXMLLoader loader = new FXMLLoader(getClass().getResource("anwendung.fxml"));
//Parent root = loader.load();
//Keep in mind that you are calling a static method
Parent root = FXMLLoader.load(getClass().getResource("anwendung.fxml"));
primaryStage.setTitle("Benutzerverwaltung");
root.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(new Scene(root));
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
Controller:
package application;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
public class AnwendungsController {
#FXML
private Button closeButton;
#FXML
void handleCloseButtonAction(ActionEvent event) {
}
#FXML
void onMouseClickedCancelBtn(MouseEvent event) {
}
}
FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="140.0" prefWidth="350.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.AnwendungsController">
<children>
<Button fx:id="closeButton" layoutX="18.0" layoutY="100.0" mnemonicParsing="false" onAction="#handleCloseButtonAction" onMouseClicked="#onMouseClickedCancelBtn" prefHeight="26.0" prefWidth="77.0" text="Abbrechen" />
<Label layoutX="10.0" layoutY="27.0" prefHeight="27.0" prefWidth="342.0" text="Sie können das Systema nun verwenden" textAlignment="CENTER" textOverrun="CLIP">
<font>
<Font name="System Bold" size="18.0" />
</font>
</Label>
</children>
</AnchorPane>
Related
How do i center this image horizontally? I've tried putting in a HBox like so, however it does not work...
<HBox alignment="CENTER">
<ImageView fitWidth="300" preserveRatio="true">
<image>
<Image url="#Logo.png"/>
</image>
</ImageView>
</HBox>
Here a little MCVE with a FXML file:
Application:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* #author Naoghuman
*/
public class CenterImageInHBox extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
FXML file:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="center.image.in.hbox.FXMLDocumentController">
<children>
<VBox layoutX="60.0" prefHeight="200.0" prefWidth="100.0" spacing="7.0" style="-fx-background-color: YELLOWGREEN;" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
<children>
<ToolBar prefHeight="40.0" prefWidth="200.0">
<items>
<Button mnemonicParsing="false" onAction="#onActionLeft" text="Left" />
<Button mnemonicParsing="false" onAction="#onActionCenter" text="Center" />
<Button mnemonicParsing="false" onAction="#onActionRight" text="Right" />
</items>
</ToolBar>
<HBox fx:id="hbImage" alignment="TOP_CENTER" VBox.vgrow="ALWAYS">
<children>
<ImageView fx:id="ivImage" fitHeight="128.0" fitWidth="128.0" pickOnBounds="true" preserveRatio="true" />
</children>
</HBox>
</children>
</VBox>
</children>
</AnchorPane>
and the Controller:
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
/**
*
* #author Naoghuman
*/
public class FXMLDocumentController implements Initializable {
#FXML private HBox hbImage;
#FXML private ImageView ivImage;
#Override
public void initialize(URL url, ResourceBundle rb) {
Image img = new Image("http://icons.iconarchive.com/icons/evermor-design/galaxian/128/Movie-Clip-icon.png");
ivImage.setImage(img);
}
public void onActionCenter() {
hbImage.setAlignment(Pos.TOP_CENTER);
}
public void onActionLeft() {
hbImage.setAlignment(Pos.TOP_LEFT);
}
public void onActionRight() {
hbImage.setAlignment(Pos.TOP_RIGHT);
}
}
When you click on the buttons in the application then you will see that the image is aligned left, center or right depends from your the choosen action.
Well, my question is simple.
I am building an application with Java Fx, and I have a TabPane.
When I open a new Tab, that Tab gets it's content by a fxml file.
tab.setContent((Node)FXMLLoader.load(this.getClass().getResource("/main/textEditor.fxml")))
Fine, that works well, it always loads the same file on all Tabs, so, all textarea on all tabs have the same id.
The problem is, with java, I can only get the information of the textarea of the first Tab.
How can i edit specifically the textarea of one tab in particular?
An example of what i want to do :
Main
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Screen;
import javafx.stage.Stage;
public class Main extends Application{
public static void main(String[] args) {
Application.launch(Main.class, args);
}
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/tabPane/test.fxml"));
Screen screen = Screen.getPrimary();
Rectangle2D bounds = screen.getVisualBounds();
stage.setScene(new Scene(root));
stage.show();
}
}
test.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.layout.AnchorPane?>
<VBox prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="tabPane.controller">
<children>
<MenuBar VBox.vgrow="NEVER">
<menus>
<Menu mnemonicParsing="false" onAction="#test" text="File">
<items>
<MenuItem fx:id="insert" mnemonicParsing="false" onAction="#test" text="Insert" />
</items>
</Menu>
</menus>
</MenuBar>
<AnchorPane maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS">
<children>
<Label alignment="CENTER" layoutX="155.0" layoutY="177.0" style="
" text="Drag components from Library here…" textAlignment="CENTER" textFill="#9f9f9f" wrapText="false">
<font>
<Font size="18.0" />
</font>
</Label>
<TabPane fx:id="tabPane" prefHeight="375.0" prefWidth="640.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab text="Untitled Tab 1">
<content>
<TextArea fx:id="textarea" prefHeight="200.0" prefWidth="200.0" text="a" />
</content>
</Tab>
<Tab text="Untitled Tab 2">
<content>
<TextArea fx:id="textarea1" prefHeight="200.0" prefWidth="200.0" text="a" />
</content>
</Tab>
</tabs>
</TabPane>
</children>
</AnchorPane>
</children>
<stylesheets>
<URL value="#../../../../BasicApplicatio11n_css/BasicApplication.css" />
controller.java
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextArea;
public class controller implements Initializable{
#FXML
private TextArea textarea;
#Override
public void initialize(URL arg0, ResourceBundle arg1) {
}
public void test(ActionEvent event){
textarea.appendText("Text");
}
}
There are two tabs on this example, when the button is pressed, I want to add the text on the current selected tab.
There are a few different ways to do this. One way is to let the controller for the tab content expose the textProperty from the text area. Then in your "main controller", create a StringProperty field. When you create a new tab, just observe its selected property and update the string property field to point to the one from the current controller. Then you can easily load text into the "current" pane.
Here's a simple example of this:
EditorController:
import javafx.beans.property.StringProperty;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
public class EditorController {
#FXML
private TextArea textArea ;
public StringProperty textProperty() {
return textArea.textProperty() ;
}
}
with textEditor.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.TextArea?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="EditorController">
<center>
<TextArea fx:id="textArea"/>
</center>
</BorderPane>
And then the MainController could look like:
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import javafx.beans.property.StringProperty;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.stage.FileChooser;
public class MainController {
#FXML
private TabPane tabPane ;
private StringProperty currentText ;
public void initialize() throws IOException {
// load an initial tab:
newTab();
}
#FXML
private void newTab() throws IOException {
Tab tab = new Tab("Untitled text");
FXMLLoader loader = new FXMLLoader(getClass().getResource("textEditor.fxml"));
tab.setContent(loader.load());
EditorController controller = loader.getController() ;
tab.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
if (isNowSelected) {
currentText = controller.textProperty();
}
});
tabPane.getTabs().add(tab);
tabPane.getSelectionModel().select(tab);
}
#FXML
private void load() {
FileChooser chooser = new FileChooser();
File file = chooser.showOpenDialog(tabPane.getScene().getWindow());
if (file != null) {
Path path = file.toPath();
try {
currentText.set(String.join("\n", Files.readAllLines(path)));
} catch (IOException e) {
Alert alert = new Alert(AlertType.ERROR);
alert.setContentText("Unable to load file "+path);
alert.setTitle("Load error");
alert.showAndWait();
}
tabPane.getSelectionModel().getSelectedItem().setText(path.getFileName().toString());
}
}
}
with main.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="MainController">
<center>
<TabPane fx:id="tabPane"/>
</center>
<bottom>
<HBox alignment="CENTER" spacing="5">
<padding>
<Insets top="5" right="5" left="5" bottom="5" />
</padding>
<Button text="Load..." onAction="#load" />
<Button text="New" onAction="#newTab"/>
</HBox>
</bottom>
</BorderPane>
For completeness, a simple application class:
import java.io.IOException;
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 IOException {
Parent root = FXMLLoader.load(getClass().getResource("main.fxml"));
Scene scene = new Scene(root, 800, 800);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
There are other approaches, e.g. you could just change the button's onAction property when the tab selection changes, etc.
So I've been following a tutorial for JavaFX and I used SceneBuilder to make a FXML view for my application. However, I can't seem to get anything to show up when I run the application - what am I doing wrong? I get no exceptions, adn the code compiles and runs fine. Here's my code.
import java.io.IOException;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Driver extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("interface.fxml"));
Pane root=null;
try {
root = (Pane) loader.load();
}
catch (IOException e) {
e.printStackTrace();
}
Scene scene = new Scene(root);
primaryStage.setTitle("Wiki Scraper");
primaryStage.setScene(scene);
primaryStage.show();
}
}
Here is interace.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<AnchorPane 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>
<Button layoutX="500.0" layoutY="351.0" mnemonicParsing="false" prefHeight="35.0" prefWidth="86.0" text="Scrape!" />
<TextArea layoutX="185.0" layoutY="41.0" prefHeight="298.0" prefWidth="401.0" />
<Label layoutX="350.0" layoutY="6.0" text="Console">
<font>
<Font size="24.0" />
</font>
</Label>
<TextField layoutX="14.0" layoutY="41.0" />
<Label layoutX="14.0" layoutY="24.0" text="URL to Start From" />
</children>
</AnchorPane>
I read a lot of posts with the same problem, but I can't fix it and find a usefull answer.
I want to create an application with the option to open a new window to enter, edit, delete some data.
I have a Main.java shown like this:
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("MainWindow.fxml"));
Scene scene = new Scene(root, 1000, 700);
stage.setTitle("FXML Welcome");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
And for this I have a MainWindowController.java
import java.net.URL;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import java.sql.*;
import java.util.ResourceBundle;
import javafx.scene.control.ComboBox;
import java.sql.Connection;
import java.sql.ResultSet;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
public class MainWindowController implements Initializable {
String ComboCompany = null;
String ComboModellName = null;
String ComboTyp = null;
#FXML
protected void handelAddButtonAction(ActionEvent event) {
System.out.println("Add");
}
#FXML
protected void handelEditButtonAction(ActionEvent event) {
System.out.println("edit");
}
#FXML
protected void handelUpdateButtonAction(ActionEvent event) {
System.out.println("update");
}
#FXML
protected void handelDelButtonAction(ActionEvent event) {
System.out.println("del");
}
#FXML
protected void handelCloseButtonAction(ActionEvent event) {
Platform.exit();
}
#Override
public void initialize(URL url, ResourceBundle rb) {
}
}
A new AddWindow.fxml is creates and ready to use. Shall I have to create a new AddWindowController.java or can I write some code in a new class?
The biggest question is, how can I solve that I click on the button "Add" that a new window pops up to enter data and close it?
Exception:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1762)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1645)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8216)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3724)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3452)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1728)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2461)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:348)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:273)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:382)
at com.sun.glass.ui.View.handleMouseEvent(View.java:553)
at com.sun.glass.ui.View.notifyMouse(View.java:925)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$141(WinApplication.java:102)
at com.sun.glass.ui.win.WinApplication$$Lambda$37/1147985808.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1757)
... 47 more
Caused by: java.lang.IllegalStateException: Location is not set.
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2428)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2403)
at multiscreeninput.MainWindowController.openInputWindow(MainWindowController.java:26)
... 57 more
I have created a small example based on your question, in which we can edit the text of a Label present on the MainWindow, using a child window.
It takes input from a TextField preset in the child window and updates the Label on the MainWindow.
You can use the same to add the other requirement as well.
All files are inside a package multiscreeninput
Main.java
package multiscreeninput;
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("/multiscreeninput/MainWindow.fxml"));
Scene scene = new Scene(root, 200, 200);
stage.setTitle("FXML Welcome");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
MainWindow.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" fx:controller="multiscreeninput.MainWindowController" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
<children>
<Label fx:id="label" text="Use to button to edit data" wrapText="true" />
</children>
</HBox>
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
<children>
<Button fx:id="button" mnemonicParsing="false" onAction="#openInputWindow" text="Change Text" />
</children>
</HBox>
</children>
</VBox>
MainWindowController.java
package multiscreeninput;
import java.io.IOException;
import javafx.beans.property.StringProperty;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
public class MainWindowController {
#FXML
Button button;
#FXML
Label label;
public void openInputWindow(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Child.fxml"));
VBox newWindow = (VBox)loader.load();
ChildController controller = loader.getController();
controller.setMainWindow(this);
Stage stage = new Stage();
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(button.getScene().getWindow());
Scene scene = new Scene(newWindow);
stage.setScene(scene);
stage.show();
}
public StringProperty getLabelTextProperty() {
return label.textProperty();
}
}
Child.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<VBox alignment="CENTER" fillWidth="false" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="200.0" spacing="20.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="multiscreeninput.ChildController">
<children>
<TextField fx:id="text">
<VBox.margin>
<Insets />
</VBox.margin></TextField>
<Button fx:id="button" mnemonicParsing="false" onAction="#saveAndClose" text="Save and Close" />
</children>
<padding>
<Insets top="10.0" />
</padding>
</VBox>
ChildController.java
package multiscreeninput;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
public class ChildController {
#FXML
TextField text;
#FXML
Button button;
private MainWindowController mainWindow;
public void setMainWindow(MainWindowController mainWindow){
this.mainWindow = mainWindow;
}
public void saveAndClose(ActionEvent event){
mainWindow.getLabelTextProperty().bind(text.textProperty());
((Button)event.getSource()).getScene().getWindow().hide();
}
}
I have a sample code which opens ROOT -> FATHER -> SON -> GRANDSON windows in that order. There is no other processing involved, just click on NEXT button and it will open it's child. This was developed in Netbeans IDE version 8.02 and JavaFX version 8x.
This is the Main Program - TESTMULTILEVEL.JAVA which opens the ROOTWindow.FXML
package testmultilevel;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* #author Hornigold Arthur
*/
public class TestMultiLevel extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("RootWindow.fxml"));
Scene scene = new Scene(root,300,300);
stage.setTitle("This is the ROOT WINDOW");
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
This is the ROOT FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" style="-fx-background-color: cornsilk; -fx-border-color: red; -fx-border-style: solid; -fx-border-width: 3;" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="testmultilevel.RootWindowController">
<children>
<Button fx:id="btnNext" layoutX="126.0" layoutY="161.0" onAction="#handleBtnNext" text="Next">
<font>
<Font name="Bookman Old Style Bold" size="14.0" />
</font></Button>
<Label fx:id="label" layoutX="84.0" layoutY="32.0" minHeight="16" minWidth="69" text="This is the ROOT" textAlignment="CENTER">
<font>
<Font name="Bookman Old Style Bold" size="14.0" />
</font></Label>
</children>
</AnchorPane>
This is the ROOT Program
package testmultilevel;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.beans.property.StringProperty;
import javafx.scene.layout.AnchorPane;
public class RootWindowController {
#FXML
private ResourceBundle resources;
#FXML
private URL location;
#FXML
private Button btnNext;
#FXML
private Label label;
#FXML
void handleBtnNext(ActionEvent event) {
System.out.println("Opening the FATHER Window");
try {
openInputWindow(event);
} catch (IOException ex) {
Logger.getLogger(RootWindowController.class.getName()).log(Level.SEVERE, null, ex);
}
}
#FXML
void initialize() {
assert btnNext != null : "fx:id=\"btnNext\" was not injected: check your FXML file 'RootWindow.fxml'.";
assert label != null : "fx:id=\"label\" was not injected: check your FXML file 'RootWindow.fxml'.";
}
public void openInputWindow(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Father.fxml"));
AnchorPane newWindow = (AnchorPane) loader.load();
FatherController controller = loader.getController();
controller.setMainWindow(this);
Stage stage = new Stage();
stage.setTitle("Father Window");
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(btnNext.getScene().getWindow());
Scene scene = new Scene(newWindow);
stage.setScene(scene);
stage.show();
}
}
This is the FATHER FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" style="-fx-background-color: cornsilk; -fx-border-color: red; -fx-border-style: solid; -fx-border-width: 3;" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="testmultilevel.FatherController">
<children>
<Button fx:id="btnNext" layoutX="126.0" layoutY="161.0" onAction="#handleBtnNext" text="Next">
<font>
<Font name="Bookman Old Style Bold" size="14.0" />
</font></Button>
<Label fx:id="label" layoutX="84.0" layoutY="32.0" minHeight="16" minWidth="69" text="This is the FATHER" textAlignment="CENTER">
<font>
<Font name="Bookman Old Style Bold" size="14.0" />
</font></Label>
</children>
</AnchorPane>
This is the FATHER Controller
package testmultilevel;
import static java.awt.SystemColor.text;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.beans.property.StringProperty;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
public class FatherController {
#FXML
private ResourceBundle resources;
#FXML
private URL location;
#FXML
private Button btnNext;
#FXML
private Label label;
private RootWindowController rootWindow;
public void setMainWindow(RootWindowController rootWindow){
this.rootWindow = rootWindow;
}
#FXML
void handleBtnNext(ActionEvent event) {
System.out.println("Opening the Son Window");
try {
openInputWindow(event);
} catch (IOException ex) {
Logger.getLogger(RootWindowController.class.getName()).log(Level.SEVERE, null, ex);
}
}
#FXML
void initialize() {
assert btnNext != null : "fx:id=\"btnNext\" was not injected: check your FXML file 'RootWindow.fxml'.";
assert label != null : "fx:id=\"label\" was not injected: check your FXML file 'RootWindow.fxml'.";
}
public void openInputWindow(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Son.fxml"));
AnchorPane newWindow = (AnchorPane) loader.load();
SonController controller = loader.getController();
controller.setMainWindow(this);
Stage stage = new Stage();
stage.setTitle("Son Window");
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(btnNext.getScene().getWindow());
Scene scene = new Scene(newWindow);
stage.setScene(scene);
stage.show();
}
}
This is the SON FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" style="-fx-background-color: cornsilk; -fx-border-color: red; -fx-border-style: solid; -fx-border-width: 3;" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="testmultilevel.SonController">
<children>
<Button fx:id="btnNext" layoutX="126.0" layoutY="161.0" onAction="#handleBtnNext" text="Next">
<font>
<Font name="Bookman Old Style Bold" size="14.0" />
</font></Button>
<Label fx:id="label" layoutX="84.0" layoutY="32.0" minHeight="16" minWidth="69" text="This is the SON" textAlignment="CENTER">
<font>
<Font name="Bookman Old Style Bold" size="14.0" />
</font></Label>
</children>
</AnchorPane>
This is the SON Controller
package testmultilevel;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
public class SonController {
#FXML
private ResourceBundle resources;
#FXML
private URL location;
#FXML
private Button btnNext;
#FXML
private Label label;
private FatherController FatherWindow;
public void setMainWindow(FatherController FatherWindow){
this.FatherWindow = FatherWindow;
}
#FXML
void handleBtnNext(ActionEvent event) {
System.out.println("Opening the Grand Son Window");
try {
openInputWindow(event);
} catch (IOException ex) {
Logger.getLogger(RootWindowController.class.getName()).log(Level.SEVERE, null, ex);
}
}
#FXML
void initialize() {
assert btnNext != null : "fx:id=\"btnNext\" was not injected: check your FXML file 'RootWindow.fxml'.";
assert label != null : "fx:id=\"label\" was not injected: check your FXML file 'RootWindow.fxml'.";
}
public void openInputWindow(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("GrandSon.fxml"));
AnchorPane newWindow = (AnchorPane) loader.load();
GrandSonController controller = loader.getController();
controller.setMainWindow(this);
Stage stage = new Stage();
stage.setTitle("Grand Son Window");
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(btnNext.getScene().getWindow());
Scene scene = new Scene(newWindow);
stage.setScene(scene);
stage.show();
}
}
This is the GRAND SON FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" style="-fx-background-color: cornsilk; -fx-border-color: red; -fx-border-style: solid; -fx-border-width: 3;" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="testmultilevel.GrandSonController">
<children>
<Button fx:id="btnNext" layoutX="126.0" layoutY="161.0" onAction="#handleBtnNext" text="Next">
<font>
<Font name="Bookman Old Style Bold" size="14.0" />
</font></Button>
<Label fx:id="label" layoutX="84.0" layoutY="32.0" minHeight="16" minWidth="69" text="This is the GRANDSON" textAlignment="CENTER">
<font>
<Font name="Bookman Old Style Bold" size="14.0" />
</font></Label>
</children>
</AnchorPane>
This is the GRAND SON Controller.
package testmultilevel;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
public class GrandSonController {
#FXML
private ResourceBundle resources;
#FXML
private URL location;
#FXML
private Button btnNext;
#FXML
private Label label;
private SonController SonWindow;
public void setMainWindow(SonController SonWindow){
this.SonWindow = SonWindow;
}
#FXML
void handleBtnNext(ActionEvent event) {
}
#FXML
void initialize() {
assert btnNext != null : "fx:id=\"btnNext\" was not injected: check your FXML file 'RootWindow.fxml'.";
assert label != null : "fx:id=\"label\" was not injected: check your FXML file 'RootWindow.fxml'.";
}
}
I did not try to Generalize the creating the Child window as a separate function and call it with appropriate parameters, so that I don't have to repeat the following piece of code in each CONTROLLER.
public void openInputWindow(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("GrandSon.fxml"));
AnchorPane newWindow = (AnchorPane) loader.load();
GrandSonController controller = loader.getController();
controller.setMainWindow(this);
Stage stage = new Stage();
stage.setTitle("Grand Son Window");
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(btnNext.getScene().getWindow());
Scene scene = new Scene(newWindow);
stage.setScene(scene);
stage.show();
}
I have this controller:
package cz.vutbr.feec.bmds.cv2;
import java.awt.Button;
import java.awt.TextField;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Slider;
public class TestGuiController {
private int buttonPressed = 0;
#FXML
private Button tlacitko;
#FXML
private TextField textovePole;
#FXML
private Slider slider;
public void buttonPressed(ActionEvent e) {
buttonPressed++;
textovePole.setText(Integer.toString(buttonPressed));
}
}
this fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>
<AnchorPane prefHeight="200.0" prefWidth="200.0" xmlns:fx="http://javafx.com/fxml" fx:controller="cz.vutbr.feec.bmds.cv2.TestGuiController">
<children>
<Button fx:id="tlacitko" layoutX="30.0" layoutY="40.0" mnemonicParsing="false" onTouchPressed="#buttonPressed" text="Button" />
<Slider fx:id="slider" layoutX="157.0" layoutY="17.0" orientation="VERTICAL" />
<TextField fx:id="textovePole" layoutX="14.0" layoutY="89.0" prefWidth="134.0" />
</children>
</AnchorPane>
and this is my main class:
package cz.vutbr.feec.bmds.cv2;
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("TestGui.fxml"));
primaryStage.setTitle("Titulek");
primaryStage.setScene(new Scene(root,300,275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
When I run this through ant I get message box with error (exception during running application). I tried simple fxml without controller and it works so I am guesing I do something wrong with controller. What I must change to have it working?
I must answer my own question. Problem was in TestGuiController where I used java.awt.Button and java.awt.TextField instead of javafx.scene.control.Button and javafx.scene.control.TextField.
I'm not 100% sure but try:
in FXML: Button: onAction instead of onTouchPressed
Please provide the exact Exception message.