I am trying to launch the IntLogin window from the main class (MAAWB); however, I can not seem to get it to launch. My splash screen launches without issues. I ran a debug with no issues until it hits the launch sequence then it kicks back an unrecognizable error. I have included below the main, fxml and controller file. What am I missing or doing wrong here that's causing me all these headaches? Also if anyone has the answer how do I put my splash screen on a timer?
main
package javafxswingapplication3;
import javafx.application.Application;
import javafx.application.Preloader;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class MAAWB extends Application {
#Override
public void start(Stage primaryStage) {
Parent root;
try {
root = FXMLLoader.load(getClass().getResource("Intlogin.fxml"));
Stage stage = new Stage();
stage.setTitle("initial login");
stage.setScene(new Scene(root, 222, 484));
stage.show();
} catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
Preloader.launch(MAAWBPreloader.class, args);
Application.launch(MAAWB.class, args);
}
}
fxml
<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.effect.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="222.0" prefWidth="484.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxswingapplication3.IntloginController">
<children>
<TextField layoutX="173.0" layoutY="50.0" />
<TextField fx:id="username" editable="false" layoutX="173.0" layoutY="90.0" />
<ChoiceBox layoutX="173.0" layoutY="130.0" prefHeight="31.0" prefWidth="187.0" />
<Label layoutX="91.0" layoutY="55.0" text="Installation" />
<Label layoutX="94.0" layoutY="95.0" text="Username" />
<Label layoutX="58.0" layoutY="135.0" text="Functional Area" />
<Button cancelButton="true" layoutX="400.0" layoutY="182.0" mnemonicParsing="false" text="Cancel" />
<Button layoutX="327.0" layoutY="182.0" mnemonicParsing="false" text="Submit" />
</children>
</AnchorPane>
controller
package javafxswingapplication3;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.Properties;
import static javafx.application.ConditionalFeature.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;
public class IntloginController implements Initializable {
private TextField username;
#Override
public void initialize(URL url, ResourceBundle rb) {
final String UN = System.getProperty("user.name");
username.setText(UN);
}
}
error
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
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 javafxswingapplication3.MAAWB.start(MAAWB.java:31)
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(Thread.java:745)
Caused by: java.lang.NullPointerException
at javafxswingapplication3.IntloginController.initialize(IntloginController.java:28)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
Annotate the username definition #FXML.
#FXML
private TextField username;
This will associate the TextField defined in your controller with the textfield defined in your FXML via fx:id="username".
Related
I'm trying from yesterday javaFX and scene builder in a very simple application to get button click to work, but everything I tried(by following some tutorials or related answers here) it doesn't work.
I created a new javaFX project and these are the files created with my editings:
Main.java:
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.fxml.FXMLLoader;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new
FXMLLoader(getClass().getResource("sample.fxml"));
loader.setController(new SampleController());
Pane root = loader.load();
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource
("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
SampleControler.java:
package application;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
public class SampleController implements Initializable{
#FXML
Button bOk;
#FXML
Label lbTest;
private void handleButtonAction(ActionEvent event) {
// Button was clicked, do something...
lbTest.setText("Button Action\n");
}
#Override
public void initialize(URL location, ResourceBundle resources) {
// TODO Auto-generated method stub
bOk.setOnAction(this::handleButtonAction);
}
}
sample.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.Pane?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="220.0" prefWidth="484.0"
xmlns="http://javafx.com/javafx/8.0.111"
xmlns:fx="http://javafx.com/fxml/1">
<children>
<Button id="bOk" layoutX="214.0" layoutY="152.0"
mnemonicParsing="false" text="Button" />
<Label id="lbTest" layoutX="214.0" layoutY="57.0" prefHeight="25.0"
prefWidth="138.0" text="Label" />
</children>
</Pane>
The above doesn't give any error, but when button clicked it doesn't do anything(supposed to change Label' s text).
I tried to set onAction on fxml file but this always gives error(cannot resolve onAction), no matter what I put there or if I do it from scene builder or by manually edit the fxml file(I have created the method and wrote it correct in onAction).
What I'm doing wrong?
The error I'm getting now:
javafx.fxml.LoadException:
/home/workspace/testapp/bin/application/sample.fxml
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2579)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
at application.Main.start(Main.java:16)
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.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$null$49(GtkApplication.java:139)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at application.SampleController.initialize(SampleController.java:27)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2548)
After I used fx:id instead of id for button and label the button worked as expected and the above errors gone.
You forgot to use the controller with the fxml:
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
minWidth="-Infinity" prefHeight="220.0" prefWidth="484.0"
xmlns="http://javafx.com/javafx/8.0.111"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="application.SampleController">
or
FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
loader.setController(new SampleController());
Pane root = loader.load();
Furthermore you need to use fx:id instead of id attributes to inject objects to the controller:
<Button fx:id="bOk" layoutX="214.0" layoutY="152.0"
mnemonicParsing="false" text="Button" />
<Label fx:id="lbTest" layoutX="214.0" layoutY="57.0" prefHeight="25.0"
prefWidth="138.0" text="Label" />
im devlop javaFx login app from tutorial on youtube for school homework. but after click login button. the login function can't show window main scene (AdminLayout.fxml). just login window hide. Thank you
this is my Error
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:498)
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:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
... 45 more
Caused by: java.lang.NullPointerException
at mpn.manda.controller.LoginLayoutController.Login(LoginLayoutController.java:58)
... 55 more
line 58 at LoginLayoutController.java
Pane p = fxmlLoader.load(getClass().getResource("view/AdminLayout.fxml").openStream());
File LoginLayoutController.java
package mpn.manda.controller;
import java.io.IOException;
import java.net.URL;
import java.sql.SQLException;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.Initializable;
import mpn.manda.model.LoginModel;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
/**
* FXML Controller class
*
* #author Xaxxis
*/
public class LoginLayoutController implements Initializable {
public LoginModel loginModel = new LoginModel();
#FXML
private Label isConnected;
#FXML
private TextField usernameField;
#FXML
private PasswordField passwordField;
#Override
public void initialize(URL location, ResourceBundle resource) {
if (loginModel.isDbConnected()) {
isConnected.setText("Connected");
} else {
isConnected.setText("Not Connected");
}
}
public void Login (ActionEvent event) {
try {
if (loginModel.isLogin(usernameField.getText(), passwordField.getText())) {
((Node)event.getSource()).getScene().getWindow().hide();
Stage primaryStage = new Stage();
FXMLLoader fxmlLoader = new FXMLLoader();
Pane p = fxmlLoader.load(getClass().getResource("view/AdminLayout.fxml").openStream());
AdminLayoutController adminController = (AdminLayoutController)fxmlLoader.getController();
adminController.GetUser(usernameField.getText());
Scene scene = new Scene(p);
scene.getStylesheets().add(getClass().getResource("css/application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} else {
isConnected.setText("Username and password is not correct");
}
} catch (SQLException e) {
isConnected.setText("Username and password is not correct");
}
catch(IOException e) {
e.printStackTrace();
}
}
}
MainApp.java
package mpn.manda;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* #author Xaxxis
*/
public class MainApp extends Application {
#Override
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("view/LoginLayout.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("css/application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
</pre>
AdminLayoutController.java
<pre>
package mpn.manda.controller;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
/**
* FXML Controller class
*
* #author Xaxxis
*/
public class AdminLayoutController implements Initializable {
#FXML
private Label userLabel;
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
public void GetUser(String user) {
// TODO
userLabel.setText(user);
}
public void Logout(ActionEvent event) {
}
}
LoginLayout.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.net.URL?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.paint.RadialGradient?>
<?import javafx.scene.paint.Stop?>
<?import javafx.scene.text.Font?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" styleClass="mainFxmlClass" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mpn.manda.controller.LoginLayoutController">
<stylesheets>
<URL value="#/mpn/manda/css/application.css" />
</stylesheets>
<children>
<Label fx:id="isConnected" layoutX="18.0" layoutY="94.0" prefHeight="28.0" prefWidth="485.0" text="Status" textFill="#f20202">
<font>
<Font size="15.0" />
</font>
</Label>
<Label layoutX="94.0" layoutY="135.0" text="Username" />
<Label layoutX="94.0" layoutY="183.0" text="Password" />
<TextField fx:id="usernameField" layoutX="203.0" layoutY="130.0" promptText="Your username" />
<PasswordField fx:id="passwordField" layoutX="203.0" layoutY="178.0" promptText="Your password" />
<Button layoutX="203.0" layoutY="236.0" mnemonicParsing="false" onAction="#Login" prefHeight="27.0" prefWidth="78.0" text="Login..." />
<Button layoutX="288.0" layoutY="236.0" mnemonicParsing="false" prefHeight="27.0" prefWidth="78.0" text="Cancel" />
<Label layoutX="47.0" layoutY="24.0" prefHeight="59.0" prefWidth="381.0" text="Welcom To The App">
<font>
<Font size="31.0" />
</font>
<textFill>
<RadialGradient centerX="0.5" centerY="0.5" radius="0.5">
<stops>
<Stop color="#3c361c" />
<Stop color="#9a8d8d" offset="0.9330855018587361" />
<Stop color="#9a8d8d" offset="1.0" />
</stops>
</RadialGradient>
</textFill>
</Label>
</children>
</AnchorPane>
AdminLayout.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mpn.manda.controller.AdminLayoutController">
<top>
<Label fx:id="userLabel" prefHeight="17.0" prefWidth="154.0" text="Halo, " BorderPane.alignment="CENTER" />
</top>
<bottom>
<Button mnemonicParsing="false" text="Logout.." BorderPane.alignment="CENTER" />
</bottom>
</BorderPane>
The path is wrong.
getClass().getResource("view/AdminLayout.fxml")
will resolve the path relative to the current class (so it is looking for /mpn/manda/controller/view/AdminLayout.fxml). Assuming (since the resource works correctly in MainApp) the view package is mpn.manda.view (i.e. AdminLayout.fxml and LoginLayout.fxml are in the same package), you can either do
getClass().getResource("/mpn/manda/view/AdminLayout.fxml")
(note the leading /, which resolves relative to the classpath), or
MainApp.class.getResource("view/AdminLayout.fxml")
which will resolve the path relative to the MainApp class.
Do not be tempted to use .. to reference a "parent package": this might work when you are reading resources and classes from the file system (e.g. during development), but will fail if your application is bundled in a jar file (which it will be at production time).
As an aside, you should prefer loading the FXML by specifying the URL of the FXML resource, instead of the stream. This is because any resource resolutions in the FXML file itself will fail if you do not specify a URL to the FXMLLoader. So I recommend
FXMLLoader fxmlLoader = new FXMLLoader(MainApp.class.getResource("view/AdminLayout.fxml"));
Pane p = fxmlLoader.load();
// ...
If you like the structure where you have one package (view) for the FXML files and one (controller) for the controllers (I don't, FWIW), another technique you might like is to define an empty class for the purpose of resolving view resources:
package mpn.manda.view ;
public abstract class View { }
And now you can load any FXML from anywhere with
FXMLLoader loader = new FXMLLoader(View.class.getResource("LoginLayout.fxml"));
Parent root = loader.load();
and
FXMLLoader loader = new FXMLLoader(View.class.getResource("AdminLayout.fxml"));
Parent p = loader.load();
etc. etc.
Can Anybody tell me how to construct HiddenSidesPane in FXML not in the controller?
I am having the basic controller code for this but I am not able to understand how to create fxml structure from that.
Can I have something like this? Below code;
<HiddenSidesPane prefWidth="800.0" pinnedSide="TOP">
<content>
<HBox fillHeight="false" nodeOrientation="RIGHT_TO_LEFT"
prefHeight="27.0" prefWidth="800.0" AnchorPane.bottomAnchor="0.0"
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"
AnchorPane.topAnchor="3.0" StackPane.alignment="TOP_RIGHT">
<children>
<Label prefHeight="14.0" prefWidth="94.0" text="Value Date From">
<HBox.margin>
<Insets right="2.0" top="5.0" />
</HBox.margin>
</Label>
</children>
<StackPane.margin>
<Insets top="2.0" />
</StackPane.margin>
</HBox>
</content>
</HiddenSidesPane>
This how I made a fast example with the offical FXSampler of ControlsFX in mind:
Assumptions
You already set up your FXML Project and added the ControlsFX.jar as dependency on your build path.
FXMLDocument.fxml
Watch for the import statements.
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.*?>
<?import org.controlsfx.control.*?>
<StackPane xmlns:fx="http://javafx.com/fxml/1" prefHeight="200" prefWidth="320" fx:controller="javafxapplication17.FXMLDocumentController">
<children>
<HiddenSidesPane fx:id="pane">
<content>
<Label alignment="CENTER" style="-fx-background-color: white; -fx-border-color: black;" maxHeight="1000.0" maxWidth="1000.0" text="Content Node" />
</content>
<top>
<Label fx:id="pinLabel" style="-fx-background-color: rgba(0,255,0,.25);" text="(Click to pin / unpin)" alignment="CENTER" prefHeight="50.0" prefWidth="50.0" onMouseClicked="#handleMouseClicked" />
</top>
</HiddenSidesPane>
</children>
</StackPane>
FXMLController.java
Inject your variables pane and pinLabel to set them.
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Side;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import org.controlsfx.control.HiddenSidesPane;
public class FXMLDocumentController implements Initializable {
#FXML
private HiddenSidesPane pane;
#FXML
private Label pinLabel;
#FXML
private void handleMouseClicked(MouseEvent event) {
if (pane.getPinnedSide() != null) {
pinLabel.setText("(unpinned)");
pane.setPinnedSide(null);
} else {
pinLabel.setText("(pinned)");
pane.setPinnedSide(Side.TOP);
}
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
JavaFXApplication17.java
Sorry for that name :-)
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class JavaFXApplication17 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);
}
}
As far as you already know here is the JavaDoc of HiddenSidesPane: http://controlsfx.bitbucket.org/org/controlsfx/control/HiddenSidesPane.html
And if you need an example download the Zip http://fxexperience.com/downloads/controlsfx-8.40.9.zip and unzip it, there is a file controlsfx-samples-8.40.9.jar inside. Double click it and show the sources.
I've been trying button events between 2 scenes in Javafx.
This is Start.fxml (in view package):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="292.0" prefWidth="383.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="controller.StartController">
<children>
<Label fx:id="lbl1" layoutX="87.0" layoutY="60.0" prefHeight="17.0" prefWidth="209.0" />
<TextField fx:id="txt1" layoutX="87.0" layoutY="121.0" prefHeight="25.0" prefWidth="209.0" />
<Button fx:id="btn1" layoutX="171.0" layoutY="191.0" mnemonicParsing="false" onAction="#btn1Click" text="Click" />
</children>
</AnchorPane>
This is Preserences.fxml (in view package):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="292.0" prefWidth="383.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="controller.PreferencesController">
<children>
<Label fx:id="lbl2" layoutX="87.0" layoutY="60.0" prefHeight="17.0" prefWidth="209.0" />
<TextField fx:id="txt2" layoutX="87.0" layoutY="121.0" prefHeight="25.0" prefWidth="209.0" />
<Button fx:id="btn2" layoutX="171.0" layoutY="191.0" mnemonicParsing="false" onAction="#btn2Click" text="Click" />
</children>
</AnchorPane>
This is Main.fxml which is like a container for the previous 2 files.(in view package):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="481.0" prefWidth="468.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="controller.MainController">
<children>
<TabPane layoutX="14.0" layoutY="14.0" prefHeight="481.0" prefWidth="468.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<tabs>
<Tab closable="false" text="Start">
<content>
<fx:include source="Start.fxml" />
</content>
</Tab>
<Tab closable="false" text="Preferences">
<content>
<fx:include source="Preferences.fxml" />
</content>
</Tab>
</tabs>
</TabPane>
</children>
</AnchorPane>
This is StartController.java (in controller package):
package controller;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
public class StartController implements Initializable {
#FXML public static Label lbl1;
#FXML public static TextField txt1;
#FXML public static Button btn1;
#Override
public void initialize(URL location, ResourceBundle resources) {
}
#FXML private void btn1Click(ActionEvent e){
System.out.println("Button 1 clicked");
lbl1.setText(PreferencesController.txt2.getText());
}
}
This is PreferencesController.java (in controller package):
package controller;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
public class PreferencesController implements Initializable {
#FXML public static Label lbl2;
#FXML public static TextField txt2;
#FXML public static Button btn2;
#Override
public void initialize(URL location, ResourceBundle resources) {
}
#FXML private void btn2Click(ActionEvent e){
System.out.println("Button 2 clicked");
lbl2.setText(StartController.txt1.getText());
}
}
This is MainController.java (in controller package):
package controller;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;
public class MainController implements Initializable{
#Override
public void initialize(URL arg0, ResourceBundle arg1) {
}
}
Finally, this is Main.java in application package:
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("/view/Main.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
But when I clicked the buttons, it gives me the errors:
"Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException...
...
Caused by: java.lang.NullPointerException
at controller.StartController.btn1Click(StartController.java:26)
... 61 more"
Please help me! :(
OK so the NPE is being thrown on this line:
lbl1.setText(PreferencesController.txt2.getText());
At the basic Java level, are only two ways that you could get that to happen:
when lnl1 is null, or
when PreferencesController.txt2 is null.
No other explanations are possible ... given that PreferencesController.txt2 is a static field.
I'm not familiar with JavaFX or FXML, but I suspect that your mistake is declaring the fields as static. I suspect that this causes the FXML mechanisms to not inject the reference to the UI component correctly. So those variables remain as null ... and you get an NPE.
Confirmation is here: https://stackoverflow.com/a/23109125/139985. (Thanks for the link #James_D)
Good evening guys,
I am still at the very beginning of Java programming. My current target is to resize the top of a BorderPane during the launch of the initialization. For sure, it would be very beneficial to have a separate class that contains the static constants (like the value for the size).
Unfortunately, I'm always getting a NullPointerException. I gues it's something really simple that I don't see. I hope that you can help me.
Thanks a lot in advance!
package main;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
public class Main extends Application {
#FXML
Pane main_top;
#Override
public void start(Stage primaryStage) {
try {
BorderPane root = (BorderPane)FXMLLoader.load(getClass().getResource("MainGui.fxml"));
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
primaryStage.setMaximized(true);
BorderPane.layoutInArea(main_top, 0, 0, 200, GlobalProperties.MainGuiTopPaneHeight, 0, null, false, false, null, null, false);
} catch(Exception e) {
e.printStackTrace();
}
}
EDIT:
java.lang.NullPointerException
at javafx.scene.layout.Region.layoutInArea(Unknown Source)
at main.Main.start(Main.java:27)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(Unknown Source)
at com.sun.javafx.application.LauncherImpl$$Lambda$51/2117598489.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda$44/1051754451.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$164(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda$47/1401292544.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda$46/1775282465.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$141(Unknown Source)
at com.sun.glass.ui.win.WinApplication$$Lambda$37/1109371569.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
EDIT2 (MainGui.fxml):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="main.MainGuiController">
<top>
<Pane fx:id="main_top" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: #525260;" BorderPane.alignment="CENTER" />
</top>
<left>
<Pane fx:id="main_left" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: #525252;" BorderPane.alignment="CENTER" />
</left>
<center>
<Pane fx:id="main_center" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
</center>
<right>
<Pane fx:id="main_right" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: #525252;" BorderPane.alignment="CENTER" />
</right>
<bottom>
<Pane fx:id="main_bottom" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: #525260;" BorderPane.alignment="CENTER" />
</bottom>
</BorderPane>
Finally after some days of trial and error, I found a solution. Now, after it's solved it looks pretty easy ;-)
All I had to do was adding the controller initialization interface in the controller.
package main;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
public class MainGuiController implements Initializable{
//***** #author n3wton
//**** FXML declarations for MainGui.fxml
#FXML
private Pane main_top;
#FXML
private Button button1;
//***** Beginning of auto-initialized method
#Override
public void initialize(URL arg0, ResourceBundle arg1) {
button1.setPrefSize(1, 1);
main_top.setPrefSize(50, 10);
}
}