Javafx can't show main window fxml after login - javafx

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.

Related

Share the same reusable FXML component in multiple views

I have a FXML view that contains a TabView with multiple tabs.
Every Tab has it's own FXML component + controller.
I would like all tabs to report progress via a component defined defined in the main view.
I know that I can inject child controllers into the main controller via FXML.
But to my current understanding, I need to access the parent controller inside my child controllers since the component is located in the main view.
I can also access the child controllers inside the initialize method of my main view. If I follow this path, I would need to modify the child controllers to set the shared component.
This is suboptimal, since the child components would be dependent on a main view that is performing those changes.
I created a MWE to illustrate the dilemma.
The question in short:
How can I report progress of Service1 and Service2 to the progressAndStatusGrid in the main view?
Callenge in short:
Make this application not throw a NPE and report progress to the progress component ;)
MWE:
Launcher:
package org.example;
public class Launcher {
public static void main(final String[] args) {
SimpleApplication.main(args);
}
}
Application:
package org.example;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class SimpleApplication extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/MainView.fxml"));
#SuppressWarnings("unused")
MainViewController controller = fxmlLoader.getController();
final Parent root = fxmlLoader.load();
final Scene scene = new Scene(root);
primaryStage.setTitle("Hello World");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
MainController:
package org.example;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.GridPane;
import java.net.URL;
import java.util.ResourceBundle;
public class MainViewController implements Initializable {
#FXML
GridPane progressAndStatusGrid;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
}
}
MainView:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane prefHeight="150.0" prefWidth="350.0" xmlns="http://javafx.com/javafx/17.0.2-ea"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.MainViewController">
<padding>
<Insets top="4" right="4" bottom="4" left="4"/>
</padding>
<top>
</top>
<center>
<TabPane>
<Tab text="tab1" closable="false">
<fx:include fx:id="tab1" source="Tab1View.fxml"/>
</Tab>
<Tab text="tab2" closable="false">
<fx:include fx:id="tab2" source="Tab2View.fxml"/>
</Tab>
</TabPane>
</center>
<bottom>
<fx:include fx:id="progressAndStatusGrid"
source="ProgressAndStatusGridComponent.fxml"/>
</bottom>
</BorderPane>
"Shared" componentController:
package org.example;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.HBox;
import java.net.URL;
import java.util.ResourceBundle;
public class ProgressAndStatusGridComponentController implements Initializable {
#FXML
ProgressBar progressBar;
#FXML
HBox progressStatusBox;
#FXML
Label progressLabel;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
}
}
"Shared" componentView:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.layout.*?>
<GridPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.example.ProgressAndStatusGridComponentController"
hgap="4" vgap="4">
<padding>
<Insets top="4" right="4" bottom="4" left="4"/>
</padding>
<fx:define>
<ColumnConstraints fx:id="colConstraints2" percentWidth="100"/>
</fx:define>
<columnConstraints>
<fx:reference source="colConstraints2"/>
<fx:reference source="colConstraints2"/>
</columnConstraints>
<ProgressBar fx:id="progressBar" GridPane.columnIndex="0" GridPane.rowIndex="0"/>
<HBox fx:id="progressStatusBox" alignment="CENTER" spacing="4" GridPane.columnIndex="1" GridPane.rowIndex="0">
<padding>
<Insets top="4" right="4" bottom="4" left="4"/>
</padding>
<Label fx:id="progressLabel"/>
</HBox>
</GridPane>
Tab1Controller:
package org.example;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import java.net.URL;
import java.util.ResourceBundle;
public class Tab1Controller implements Initializable {
#FXML
Button button1;
Service1 service1 = new Service1();
// How to get a reference, that is already initialized?
#FXML
ProgressAndStatusGridComponentController progressAndStatusGridComponentController;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
button1.disableProperty().bind(service1.runningProperty());
}
public void handleButtonClick(ActionEvent actionEvent) {
service1.cancel();
service1.reset();
progressAndStatusGridComponentController.progressBar.progressProperty().bind(service1.progressProperty());
progressAndStatusGridComponentController.progressLabel.textProperty().bind(service1.messageProperty());
service1.start();
}
}
Tab1View:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.example.Tab1Controller">
<center>
<Button fx:id="button1" text="Start Background Progress #1" onAction="#handleButtonClick"/>
</center>
</BorderPane>
Tab2Controller:
package org.example;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import java.net.URL;
import java.util.ResourceBundle;
public class Tab2Controller implements Initializable {
#FXML
Button button2;
Service2 service2 = new Service2();
// How to get a reference, that is already initialized?
#FXML
ProgressAndStatusGridComponentController progressAndStatusGridComponentController;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
button2.disableProperty().bind(service2.runningProperty());
}
public void handleButtonClick(ActionEvent actionEvent) {
service2.cancel();
service2.reset();
progressAndStatusGridComponentController.progressBar.progressProperty().bind(service2.progressProperty());
progressAndStatusGridComponentController.progressLabel.textProperty().bind(service2.messageProperty());
service2.start();
}
}
Tab2View:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.example.Tab2Controller">
<center>
<Button fx:id="button2" text="Start Background Progress #2" onAction="#handleButtonClick"/>
</center>
</BorderPane>
Service1:
package org.example;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
public class Service1 extends Service<Void> {
static final int workLoad = 100;
#Override
protected Task<Void> createTask() {
return new Task<>() {
#Override
protected Void call() throws Exception {
updateMessage("Starting Task #1..");
for (int i = 0; i < workLoad; i++) {
Thread.sleep(200);
updateProgress(i, workLoad);
updateMessage(i + " elements done");
}
updateMessage("Task #1 done!");
return null;
}
};
}
}
Service2:
package org.example;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
public class Service2 extends Service<Void> {
static final int workLoad = 100;
#Override
protected Task<Void> createTask() {
return new Task<>() {
#Override
protected Void call() throws Exception {
updateMessage("Starting Task #2..");
for (int i = 0; i < workLoad; i++) {
Thread.sleep(200);
updateProgress(i, workLoad);
updateMessage(i + " elements done");
}
updateMessage("Task #2 done!");
return null;
}
};
}
}

Cannot import javafx fxml class

Using the FXML project template in netbeans, I've been experiencing an issue with defining the FX controller in my FXML file.
The main class, fxml document and fxml controller are all in the same package: "login".
I am importing the controller into the fxml document using it's fully qualified name.
Error occurs at the import line: "Class login.MyController does not exist."
FXML Document
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ButtonBar?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.shape.Polygon?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>
<?import login.MyController?>
<VBox prefHeight="400.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="login.MyController">
<children>
<AnchorPane maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" style="-fx-background-color: #091D34;" VBox.vgrow="ALWAYS">
<children>
<Polygon fill="#000000b1" layoutX="363.0" layoutY="103.0" points="-50.0, 40.0, 50.0, 40.0, 50.0, -73.0" stroke="BLACK" strokeType="INSIDE" style="-fx-fill: #133863;" />
<ButtonBar layoutX="233.0" layoutY="256.0" prefHeight="40.0" prefWidth="161.0">
<buttons>
<Button layoutX="135.0" layoutY="18.0" minWidth="49.0" mnemonicParsing="false" prefHeight="25.0" text="Login" onAction="#doLogin" />
<Button layoutX="165.0" layoutY="18.0" mnemonicParsing="false" text="About" />
</buttons>
</ButtonBar>
<PasswordField layoutX="186.0" layoutY="216.0" prefHeight="25.0" prefWidth="273.0" promptText="Password" onKeyPressed="#onEnter" />
<TextField layoutX="186.0" layoutY="175.0" prefHeight="25.0" prefWidth="273.0" promptText="Username" />
<Text layoutX="253.0" layoutY="76.0" strokeType="OUTSIDE" strokeWidth="0.0" style="-fx-fill: #236AB9;" text="Anatomy Law" textAlignment="CENTER" wrappingWidth="120.58984375">
<font>
<Font name="Aparajita" size="22.0" />
</font>
</Text>
</children>
</AnchorPane>
Controller
package login;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
public class MyController implements Initializable {
#FXML
public void doLogin(Event e){
System.out.println("do login called");
}
#FXML
public void onEnter(KeyEvent ke){
if(ke.getCode() == KeyCode.ENTER){
System.out.println("on enter called");
login();
}
}
private void login(){
}
#Override
public void initialize(URL location, ResourceBundle resources) {
}
}
Main
package login;
import java.net.URL;
import javafx.application.Application;
import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage stage) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader();
MyController fxmlController = new MyController();
fxmlLoader.setController(fxmlController);
fxmlLoader.setLocation(new URL("C:/.../login/Login.fxml"));
VBox vbox = fxmlLoader.<VBox>load();
Scene scene = new Scene(vbox);
stage.setScene(scene);
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Note
I recently tried the following line in my FXML document:
<?import login.*?>
Which resulted in "package login does not exist."
And
<?import MyController?>
Which resulted in class does not exist.
So i'm assuming it's some kind of build path error but they're all in the same package. I even added the package that they're in to additional source packages to build from just to make sure but that didn't solve anything. My project layout is the following:
Project Name
Source Packages
login
Login.fxml
MyController.java
Main.java
I reviewed the other question postings for this problem but no one seemed to have this specific problem. If I did however miss someone's post with an identical answer, I will gladly take that reference.
You don't have to import it. You have to specify the full name of your controller class though.
In your case it is login.MyController so fx:controller="login.MyController".
Though you might have some other problems because I'm not having any issues when i put that import statement in the fxml. It just isn't necessary.
Make sure that the document you are editing is definitely the document in your package.
Somehow, in my case I was actually editing a document outside of the package with the same exact name. This is why it couldn't find the controller class when I tried to import it.

javaFX-scene builder button event doesn't work

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" />

Unable to Call another fxml page on button click event

I am Trying to come up with simple tool where I want to Call another fxml page on a button click from present fxml page.
My Main Java class is designed as follows:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.BorderPane;
public class Main extends Application
{
#Override
public void start(Stage stage) {
try {
TitledPane page = (TitledPane)FXMLLoader.load(getClass().getResource("NewTest.fxml"));
Scene scene = new Scene(page);
stage.setScene(scene);
stage.setTitle("Welome Page");
stage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Application.launch(Main.class, (java.lang.String[])null);
}}
and Controller Class is designed as :
import javafx.event.ActionEvent;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.TitledPane;
import javafx.stage.Stage;
public class SimpleController implements Initializable
{
#FXML // fx:id="loginbtn"
private Button loginbtn; // Value injected by FXMLLoader
#Override // This method is called by the FXMLLoader when
initialization is complete
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
assert loginbtn != null : "fx:id=\"myButton\" was not injected: check your FXML file 'simple.fxml'.";
// initialize your logic here: all #FXML variables will have been injected
loginbtn.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
Stage stage;
Parent root;
if(event.getSource()==loginbtn){
//get reference to the button's stage
stage=(Stage) loginbtn.getScene().getWindow();
//load up OTHER FXML document
try{
TitledPane page =(TitledPane) FXMLLoader.load(getClass().getResource("secondPage.fxml"));
}catch(Exception e)
{e.printStackTrace();}
}
}
});
}
}
And the Fxml Page is like:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TitledPane?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<TitledPane text="Welcome to the Vacation Planner" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1">
<content>
<AnchorPane prefHeight="330.0" prefWidth="497.0">
<children>
<Label layoutX="14.0" layoutY="52.0" prefHeight="25.0" prefWidth="189.0" text="User Name">
<font>
<Font size="24.0" />
</font>
</Label>
<TextArea layoutX="53.0" layoutY="106.0" prefHeight="41.0" prefWidth="391.0" />
<Label layoutX="14.0" layoutY="165.0" text="Password">
<font>
<Font size="24.0" />
</font>
</Label>
<Button fx:id="loginbtn" layoutX="114.0" layoutY="262.0" mnemonicParsing="false" text="Login">
<font>
<Font size="18.0" />
</font>
</Button>
<Button fx:id="exitbtn" layoutX="271.0" layoutY="262.0" mnemonicParsing="false" text="Exit">
<font>
<Font size="18.0" />
</font>
</Button>
<PasswordField layoutX="53.0" layoutY="207.0" prefHeight="39.0" prefWidth="391.0" />
</children>
</AnchorPane>
</content>
</TitledPane>
When I am clicking on the button Login it is not opening the Second xml page that I am trying to open on button click.
Thanks in advance.
You load the Nodes and then do nothing with it.
You need to add them to the existing scene or replace that scene:
try{
TitledPane page =(TitledPane) FXMLLoader.load(getClass().getResource("secondPage.fxml"));
Scene newScene = new Scene(page);
stage.setScene(newScene);
} catch(Exception e) {
e.printStackTrace();
}
Furthermore you haven't associated the controller with the fxml. Use e.g. the fx:controller attribute with the fully qualified class name of the controller class at the root of the fxml to do this:
<TitledPane text="Welcome to the Vacation Planner" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="my.package.SimpleController">
Where my.package would be the package containing the controller.

HiddenSidesPane fxml example

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.

Resources