JavaFX - populating data from TableView selection to dialog box - javafx

I am learning to get data from selected row of TableView and prepopulate dialog box with that data. No matter what I do while loading dialog box I get NullPointerException in Controller.java -> showEditContactDialog()-> editController.setItem(item)).Somehow I am not able to pass selected data to another class and have it displayed by dialog box. Appreciate someone point me to the right direction. Here is the code:
Main.java:
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import sample.datamodel.ContactData;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("MainWindow.fxml"));
primaryStage.setTitle("Address Book");
primaryStage.setScene(new Scene(root, 1280, 500));
primaryStage.show();
}
#Override
public void stop(){
ContactData.getInstance().saveContacts();
}
}
Controller.java:
package sample;
#FXML
private TableView<Contact> tableView;
#FXML
private BorderPane mainBorderPane;
private Contact item;
public Controller() {
}
#FXML
public TableView<Contact> getTableView() {
return tableView;
}
#FXML
public void initialize(){
loadContacts();
tableView.setOnMouseClicked((MouseEvent event) -> {
if (event.getClickCount() > 0) {
item = tableView.getSelectionModel().getSelectedItem(); // *** get selection from TableView ***
}
});
}
#FXML
public void handleExit(){
ContactData.getInstance().saveContacts();
Platform.exit();
}
public void saveContacts() {
ContactData.getInstance().saveContacts();
}
public void loadContacts() {
ContactData.getInstance().loadContacts();
tableView.setItems(ContactData.getInstance().getContacts());
}
public void deleteContact(){
ContactData.getInstance().deleteContact(item);
}
public void showAddContactDialog(ActionEvent event) throws IOException {
Dialog<ButtonType> dialog = new Dialog<>();
dialog.initOwner(mainBorderPane.getScene().getWindow());
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("addContact.fxml"));
try{
dialog.getDialogPane().setContent(fxmlLoader.load());
}catch(IOException e){
System.out.println("Couldn't load the dialog");
e.printStackTrace();
return;
}
Optional<ButtonType> result = dialog.showAndWait();
if(result.isPresent()){
Dialog controller = fxmlLoader.getController();
}
}
public void showEditContactDialog() throws Exception {
Dialog<ButtonType> dialog = new Dialog<>();
dialog.initOwner(mainBorderPane.getScene().getWindow());
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("editContact.fxml"));
EditContactController editController = fxmlLoader.<EditContactController>getController();
editController.setItem(item); // ****** trying to pass "item" but get NullPointerException *********
try{
dialog.getDialogPane().setContent(fxmlLoader.load());
} catch (IOException e) {
System.out.println("Couldn't load the dialog");
e.printStackTrace();
return;
}
Optional<ButtonType> result = dialog.showAndWait();
}
}
EditContactController.java
package sample;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import sample.datamodel.Contact;
public class EditContactController{
#FXML
private TextField fName;
#FXML
private TextField lName;
#FXML
private TextField pNumber;
#FXML
private TextArea nNotes;
#FXML
private javafx.scene.control.Button cancelButton;
#FXML
private Contact item;
public void setItem(Contact item) {
this.item = item;
}
#FXML
public void initialize(){
try {
fName.setText(item.getFirstName());
}catch(NullPointerException e) {
System.out.println("null point --> " + e.getMessage());
e.printStackTrace();
}
}
//#FXML
public void cancelButtonAction(){
// get a handle to the stage
Stage stage = (Stage) cancelButton.getScene().getWindow();
stage.close();
}
}
editContact.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>
<GridPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.EditContactController">
<HBox GridPane.columnSpan="2">
<Label text="Edit contact">
<font>
<Font name="System Bold" size="17.0" />
</font>
<padding>
<Insets bottom="10.0" left="10.0" />
</padding></Label>
</HBox>
<Label text="First Name" GridPane.columnIndex="0" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1">
<GridPane.margin>
<Insets left="10.0" />
</GridPane.margin>
<padding>
<Insets bottom="5.0" />
</padding></Label>
<Label text="Last Name" GridPane.columnIndex="0" GridPane.rowIndex="2">
<GridPane.margin>
<Insets bottom="5.0" left="10.0" />
</GridPane.margin></Label>
<Label text="Phone number" GridPane.columnIndex="0" GridPane.rowIndex="3">
<GridPane.margin>
<Insets bottom="5.0" left="10.0" />
</GridPane.margin></Label>
<Label text="Notes" GridPane.columnIndex="0" GridPane.rowIndex="4">
<GridPane.margin>
<Insets bottom="5.0" left="10.0" />
</GridPane.margin></Label>
<TextField fx:id="fName" GridPane.columnIndex="1" GridPane.rowIndex="1">
<GridPane.margin>
<Insets bottom="5.0" />
</GridPane.margin></TextField>
<TextField fx:id="lName" GridPane.columnIndex="1" GridPane.rowIndex="2">
<GridPane.margin>
<Insets bottom="5.0" />
</GridPane.margin></TextField>
<TextField fx:id="pNumber" GridPane.columnIndex="1" GridPane.rowIndex="3">
<GridPane.margin>
<Insets bottom="5.0" />
</GridPane.margin></TextField>
<TextArea fx:id="nNotes" GridPane.columnIndex="1" GridPane.rowIndex="4">
<GridPane.margin>
<Insets bottom="5.0" />
</GridPane.margin></TextArea>
<HBox alignment="TOP_RIGHT" spacing="5.0" GridPane.columnIndex="1" GridPane.rowIndex="5">
<Button text="Edit">
<opaqueInsets>
<Insets />
</opaqueInsets></Button>
<Button fx:id="cancelButton" cancelButton="true" onAction="#cancelButtonAction" text="Cancel" />
<opaqueInsets>
<Insets />
</opaqueInsets>
<GridPane.margin>
<Insets />
</GridPane.margin>
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" />
</padding>
</HBox>
<columnConstraints>
<ColumnConstraints maxWidth="288.0" minWidth="22.0" prefWidth="129.0" />
<ColumnConstraints maxWidth="578.0" minWidth="312.0" prefWidth="471.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
</rowConstraints>
<padding>
<Insets left="5.0" right="5.0" top="5.0" />
</padding>
<opaqueInsets>
<Insets />
</opaqueInsets>
</GridPane>
Stack:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
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:8413)
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:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$353(GlassViewEventHandler.java:432)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
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:1771)
... 48 more
Caused by: java.lang.NullPointerException
at sample.Controller.showEditContactDialog(Controller.java:105)
... 58 more

Your controller class is specified in the FXML file, so the FXMLLoader cannot instantiate it until it reads that file. This means the controller is only created during the call to load(), and calling fxmlLoader.getController() prior to that will return null.
So you need to move the code that retrieves the controller and acts on it so that it is executed after you call load():
public void showEditContactDialog() throws Exception {
Dialog<ButtonType> dialog = new Dialog<>();
dialog.initOwner(mainBorderPane.getScene().getWindow());
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("editContact.fxml"));
try {
Parent dialogContent = fxmlLoader.load();
EditContactController editController = fxmlLoader.<EditContactController>getController();
editController.setItem(item);
dialog.getDialogPane().setContent(dialogContent);
} catch (IOException e) {
System.out.println("Couldn't load the dialog");
e.printStackTrace();
return;
}
Optional<ButtonType> result = dialog.showAndWait();
}
The initialize() method in the controller is also called during the call to FXMLLoader.load(). So, as a consequence of these changes, initialize() is now called before you call setItem(...) on the EditContactController. So you need to move the code that depends on the item from the initialize() method to the setItem() method:
public void setItem(Contact item) {
this.item = item;
fName.setText(item.getFirstName());
}
#FXML
public void initialize(){
}

Related

Javafx How to display image captured from web cam in imageview in another scene

I have this fxml layout. When I click on take photo it opens a screen for me to take a picture using web cam
Dialog layout to take pic from web cam
I want the picture captured on the web cam to replace the dummy image on the fxml layout beside take photo button.Here are my files:
FXML layout containing dummy image and take photo button
<HBox prefHeight="79.0" prefWidth="232.0" spacing="30.0">
<children>
<VBox prefHeight="100.0" prefWidth="100.0">
<children>
<ImageView fx:id="profilePic" fitHeight="99.0" fitWidth="118.0" nodeOrientation="INHERIT" pickOnBounds="true">
<image>
<Image url="#../images/profile_photo.png" />
</image>
</ImageView>
</children>
</VBox>
<VBox prefHeight="200.0" prefWidth="100.0">
<children>
<Button mnemonicParsing="false" onAction="#takePhoto" text="Take Photo">
<font>
<Font size="13.0" />
</font>
<VBox.margin>
<Insets bottom="20.0" top="10.0" />
</VBox.margin>
</Button>
<Button mnemonicParsing="false" onAction="#pickPhoto" prefHeight="31.0" prefWidth="85.0" text="Upload
">
<font>
<Font size="13.0" />
</font>
<VBox.margin>
<Insets bottom="10.0" />
</VBox.margin></Button>
</children>
</VBox>
</children>
</HBox>
Controller for the FXML Layout
public class AddParentController implements Initializable {
#Override
public void initialize(URL location, ResourceBundle resources) {
}
public void doAll(){
ImageSelection.getImageSelectionInstance().imageProperty()
.addListener((obs, oldImage, newImage) -> profilePic.setImage(newImage));
}
public void takePhoto(){
try {
Stage dialogStage = new Stage(StageStyle.UNDECORATED);
BorderPane root = FXMLLoader.load(getClass().getResource("../views/WebCamPreview.fxml"));
Scene scene = new Scene(root, 850, 390);
dialogStage.setUserData("fromAddParent");
dialogStage.initModality(Modality.APPLICATION_MODAL);
dialogStage.setScene(scene);
dialogStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Dialog Layout containing WebCam Preview
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.FlowPane?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>
<BorderPane prefHeight="390.0" prefWidth="850.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.controllers.WebCamPreviewController">
<!-- TODO Add Nodes -->
<bottom>
<FlowPane fx:id="fpBottomPane" alignment="CENTER" columnHalignment="CENTER" hgap="50.0" prefHeight="80.0" prefWidth="200.0" style="-fx-background-color:#ccc;">
<children>
<Button fx:id="btnStartCamera" focusTraversable="false" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#stopCamera" prefHeight="40.0" prefWidth="120.0" text="Capture">
<font>
<Font name="Segoe UI" size="18.0" fx:id="x1" />
</font>
</Button>
<Button fx:id="btnProceedCamera" focusTraversable="false" font="$x1" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#proceed" prefHeight="40.0" prefWidth="120.0" text="Proceed" />
<Button fx:id="btnResetCamera" focusTraversable="false" font="$x1" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#startCamera" prefHeight="40.0" prefWidth="120.0" text="Reset" />
<Button fx:id="btnDisposeCamera" focusTraversable="false" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#disposeCamera" prefHeight="40.0" prefWidth="120.0" text="Close">
<font>
<Font name="Segoe UI" size="18.0" fx:id="x11" />
</font>
</Button>
</children>
</FlowPane>
</bottom>
<center>
<BorderPane fx:id="bpWebCamPaneHolder" prefHeight="200.0" prefWidth="200.0">
<center>
<ImageView fx:id="imgWebCamCapturedImage" fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER" />
</center></BorderPane>
</center>
<top>
<GridPane minHeight="-Infinity" minWidth="-Infinity" prefHeight="80.0" style="-fx-background-color:#ccc;
">
<children>
<Label text="Webcam Image Capture" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.rowIndex="0" GridPane.rowSpan="1" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS">
<font>
<Font name="Segoe UI" size="34.0" />
</font>
<GridPane.margin>
<Insets top="10.0" />
</GridPane.margin>
</Label>
</children>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" maxWidth="795.0" minWidth="10.0" prefWidth="418.0" />
<ColumnConstraints hgrow="SOMETIMES" maxWidth="502.0" minWidth="10.0" prefWidth="482.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
</GridPane>
</top>
</BorderPane>
WebCam Preview Controller
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URL;
import java.util.ResourceBundle;
import com.github.sarxos.webcam.WebcamPanel;
import javafx.application.Platform;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import com.github.sarxos.webcam.Webcam;
import javafx.stage.Stage;
public class WebCamPreviewController implements Initializable {
#FXML Button btnStartCamera;
#FXML Button btnProceedCamera;
#FXML Button btnDisposeCamera,btnResetCamera;
#FXML BorderPane bpWebCamPaneHolder;
#FXML FlowPane fpBottomPane;
#FXML ImageView imgWebCamCapturedImage;
private BufferedImage grabbedImage;
private WebcamPanel selWebCamPanel = null;
private Webcam selWebCam = null;
private boolean stopCamera = false;
private ObjectProperty<Image> imageProperty = new SimpleObjectProperty<Image>();
Image mainiamge;
private String userData;
#Override
public void initialize(URL arg0, ResourceBundle arg1) {
fpBottomPane.setDisable(true);
try{
initializeWebCam(0);
}catch(Exception e){
e.printStackTrace();
}
Platform.runLater(() -> {
userData = (String) fpBottomPane.getScene().getWindow().getUserData();
setImageViewSize();
});
}
protected void setImageViewSize() {
double height = bpWebCamPaneHolder.getHeight();
double width = bpWebCamPaneHolder.getWidth();
imgWebCamCapturedImage.setFitHeight(height);
imgWebCamCapturedImage.setFitWidth(width);
imgWebCamCapturedImage.prefHeight(height);
imgWebCamCapturedImage.prefWidth(width);
imgWebCamCapturedImage.setPreserveRatio(true);
}
protected void initializeWebCam(final int webCamIndex) {
Task<Void> webCamIntilizer = new Task<Void>() {
#Override
protected Void call() throws Exception {
if(selWebCam == null)
{
selWebCam = Webcam.getWebcams().get(webCamIndex);
selWebCam.open();
}else
{
closeCamera();
selWebCam = Webcam.getWebcams().get(webCamIndex);
selWebCam.open();
}
startWebCamStream();
return null;
}
};
new Thread(webCamIntilizer).start();
fpBottomPane.setDisable(false);
btnProceedCamera.setDisable(true);
btnResetCamera.setDisable(true);
}
protected void startWebCamStream() {
stopCamera = false;
Task<Void> task = new Task<Void>() {
#Override
protected Void call() throws Exception {
while (!stopCamera) {
try {
if ((grabbedImage = selWebCam.getImage()) != null) {
Platform.runLater(new Runnable() {
#Override
public void run() {
mainiamge = SwingFXUtils
.toFXImage(grabbedImage, null);
imageProperty.set(mainiamge);
}
});
grabbedImage.flush();
}
} catch (Exception e) {
} finally {
}
}
return null;
}
};
Thread th = new Thread(task);
th.setDaemon(true);
th.start();
imgWebCamCapturedImage.imageProperty().bind(imageProperty);
}
private void closeStage() {
((Stage) fpBottomPane.getScene().getWindow()).close();
}
private void closeCamera()
{
if(selWebCam != null)
{
selWebCam.close();
}
}
public void proceed(){
ImageSelection.getImageSelectionInstance().setImage(imgWebCamCapturedImage.getImage());
AddParentController apc = new AddParentController();
apc.doAll();
closeStage();
}
public void proceedToAddPartner(){
}
public void stopCamera(ActionEvent event)
{
stopCamera = true;
btnStartCamera.setDisable(true);
btnResetCamera.setDisable(false);
btnProceedCamera.setDisable(false);
}
public void startCamera(ActionEvent event)
{
stopCamera = false;
startWebCamStream();
btnStartCamera.setDisable(false);
btnResetCamera.setDisable(true);
btnProceedCamera.setDisable(true);
}
public void disposeCamera(ActionEvent event)
{
//stopCamera = true;
//closeCamera();
//Webcam.shutdown();
//btnStopCamera.setDisable(true);
//btnStartCamera.setDisable(true);
closeStage();
}
}
Image Model
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.image.Image;
public class ImageSelection {
private final ObjectProperty<Image> image = new SimpleObjectProperty<>();
private static ImageSelection imageSelectionInstance= new ImageSelection();
private ImageSelection(){}
public static ImageSelection getImageSelectionInstance() {
return imageSelectionInstance;
}
public ObjectProperty<Image> imageProperty() {
return image ;
}
public final void setImage(Image image) {
imageProperty().set(image);
}
public final Image getImage()
{
return imageProperty().get();
}
}
The challenge is to make the Image captured by the web cam to display in profilPic ImageView on the AddParent FXML Layout.

JavaFX custom node creation

I tried creating my own custom node, but I miserably failed somehow.
It always throws me an error when I try to run the controller/scene.
This is my class representing the custom node
package com.lollookup.scene.customcontrol;
import com.lollookup.scene.data.ChampionInfoData;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javax.xml.soap.Text;
import java.io.IOException;
/**
* #author Yasin
*/
public class ChampionInfo extends Pane {
#FXML
private ImageView championImage;
#FXML
private Text KDA;
#FXML
private Text winRate;
#FXML
private Text masteryScore;
#FXML
private Text masteryLevel;
public ChampionInfo() {
try {
Parent root = FXMLLoader.load(getClass().getResource("championinfo.fxml"));
} catch (IOException e) {
e.printStackTrace();
}
}
public void setData(ChampionInfoData championInfoData) {
this.championImage.setImage(new Image(championInfoData.getUrl()));
this.KDA.setTextContent(championInfoData.getKDA());
this.winRate.setTextContent(championInfoData.getWinRate());
this.masteryScore.setTextContent(championInfoData.getMasteryScore());
this.masteryLevel.setTextContent(championInfoData.getMasteryLevel());
}
}
And this is my fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Separator?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.Text?>
<fx:root maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="84.0" prefWidth="238.0" type="Pane" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.lollookup.scene.customcontrol.ChampionInfo">
<children>
<Separator layoutY="3.0" prefHeight="0.0" prefWidth="238.0" />
<HBox prefHeight="84.0" prefWidth="200.0">
<children>
<ImageView fx:id="championImage" fitHeight="72.0" fitWidth="66.0" pickOnBounds="true" preserveRatio="true">
<HBox.margin>
<Insets left="10.0" top="10.0" />
</HBox.margin>
</ImageView>
<VBox prefHeight="200.0" prefWidth="100.0">
<children>
<Text fx:id="KDA" strokeType="OUTSIDE" strokeWidth="0.0" text="kda">
<VBox.margin>
<Insets top="10.0" />
</VBox.margin>
</Text>
<Text fx:id="winRate" strokeType="OUTSIDE" strokeWidth="0.0" text="winRate" />
<Text fx:id="masteryLevel" strokeType="OUTSIDE" strokeWidth="0.0" text="champLevel" />
<Text fx:id="masteryScore" strokeType="OUTSIDE" strokeWidth="0.0" text="champScore" />
</children>
<HBox.margin>
<Insets left="10.0" />
</HBox.margin>
</VBox>
</children>
</HBox>
<Separator layoutY="79.0" prefHeight="0.0" prefWidth="238.0" />
</children>
</fx:root>
My problem now is that somehow I can't really start/implement the custom node.
So no matter if I create a Scene like this:
package com.lollookup.scene.customcontrol;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
* #author Yasin
*/
public class ChampionInfoExample extends Application {
#Override
public void start(Stage stage) throws Exception {
//ChampionInfo championInfo = new ChampionInfo(new ChampionInfoData("https://placeholdit.imgix.net/~text?txtsize=33&txt=350%C3%97150&w=350&h=150", "1:1", "50%", "0", "1"));
ChampionInfo championInfo = new ChampionInfo();
//championInfo.setData(new ChampionInfoData("https://placeholdit.imgix.net/~text?txtsize=33&txt=350%C3%97150&w=350&h=150", "1:1", "50%", "0", "1"));
stage.setScene(new Scene(championInfo));
stage.setTitle("Custom Control");
stage.setWidth(300);
stage.setHeight(200);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
or instantiate it like that:
Stream.of(championData).forEach(p -> championDataContainer.getChildren().add(new ChampionInfo()));
This is what is being thrown:
Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.StackOverflowError
at java.net.URLStreamHandler.setURL(URLStreamHandler.java:537)
at java.net.URLStreamHandler.parseURL(URLStreamHandler.java:304)
at sun.net.www.protocol.file.Handler.parseURL(Handler.java:67)
at java.net.URL.<init>(URL.java:615)
at java.net.URL.<init>(URL.java:483)
at sun.misc.URLClassPath$FileLoader.getResource(URLClassPath.java:1222)
at sun.misc.URLClassPath$FileLoader.findResource(URLClassPath.java:1212)
at sun.misc.URLClassPath$1.next(URLClassPath.java:240)
at sun.misc.URLClassPath$1.hasMoreElements(URLClassPath.java:250)
at java.net.URLClassLoader$3$1.run(URLClassLoader.java:601)
at java.net.URLClassLoader$3$1.run(URLClassLoader.java:599)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader$3.next(URLClassLoader.java:598)
at java.net.URLClassLoader$3.hasMoreElements(URLClassLoader.java:623)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at java.util.ServiceLoader$LazyIterator.hasNextService(ServiceLoader.java:354)
at java.util.ServiceLoader$LazyIterator.hasNext(ServiceLoader.java:393)
at java.util.ServiceLoader$1.hasNext(ServiceLoader.java:474)
at javax.xml.stream.FactoryFinder$1.run(FactoryFinder.java:352)
at java.security.AccessController.doPrivileged(Native Method)
at javax.xml.stream.FactoryFinder.findServiceProvider(FactoryFinder.java:341)
at javax.xml.stream.FactoryFinder.find(FactoryFinder.java:313)
at javax.xml.stream.FactoryFinder.find(FactoryFinder.java:227)
at javax.xml.stream.XMLInputFactory.newInstance(XMLInputFactory.java:154)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2472)
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 com.lollookup.scene.customcontrol.ChampionInfo.<init>(ChampionInfo.java:38)
at sun.reflect.GeneratedConstructorAccessor2.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
What should I do?
I'd appreciate any kind of assistance
Thanks
Edit:
After debugging, I kinda found out why it was null. Had nothing to do with the codes given. Thank you StackOverflow!

JavaFX Adding Rows to TableView on Different Page

Okay, I've been working through some issues with this program and I think I've finally gotten it to a point where I understand what is wrong. I'm trying to follow this tutorial a bit: http://docs.oracle.com/javafx/2/fxml_get_started/fxml_tutorial_intermediate.htm But my program has the add a row on a different FXML page than the Table View is on. I think the program is having trouble connecting the two. I've looked in to trying to find ways to make them talk to each other (put everything in one Controller and it didn't like it, tried passing the controller through the class and that didn't work {might have done it wrong though}). My program also has Integers and Doubles in it which are not covered in that tutorial so I've tried to figure those out on my own (probably better ways of doing it than I did).
But right now I'm just focused on figuring out why it keeps thinking
data = partTable.getItems();
Is null (line 77 in AddPartController). Any help or other FXML/JavaFX tutorials would be greatly appreciated (though I've already looked through a lot of them).
FXMLDocument.fxml (main page)
<?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.scene.control.cell.*?>
<?import javafx.collections.*?>
<?import fxmltableview.*?>
<?import ims.Part?>
<?import ims.Inhouse?>
<?import ims.Outsourced?>
<BorderPane id="main" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ims.FXMLDocumentController" >
<top>
<Label fx:id="mainTitle" text="Inventory Management System" />
</top>
<center>
<HBox fx:id="holding">
<children>
<VBox styleClass="contentBox">
<children>
<HBox styleClass="topBox">
<HBox styleClass="subHeading">
<Label text="Parts" />
</HBox>
<HBox styleClass="searchBox">
<Button text="Search" />
<TextField />
</HBox>
</HBox>
<TableView fx:id="partTable" styleClass="dataTable">
<columns>
<TableColumn text="Part ID">
<cellValueFactory>
<PropertyValueFactory property="id" />
</cellValueFactory>
</TableColumn>
<TableColumn fx:id="nameColumn" text="Part Name">
<cellValueFactory>
<PropertyValueFactory property="name" />
</cellValueFactory>
</TableColumn>
<TableColumn text="Inventory Level">
<cellValueFactory>
<PropertyValueFactory property="instock" />
</cellValueFactory>
</TableColumn>
<TableColumn text="Price/Cost per Unit">
<cellValueFactory>
<PropertyValueFactory property="price" />
</cellValueFactory>
</TableColumn>
</columns>
<items>
<FXCollections fx:factory="observableArrayList">
<Inhouse name="Part 1" price="5.00" instock="5" max="10" min="1" />
<Inhouse name="Part 2" price="7.00" instock="2" max="11" min="2" />
</FXCollections>
</items>
<sortOrder>
<fx:reference source="nameColumn" />
</sortOrder>
</TableView>
<HBox styleClass="modificationButtons">
<children>
<Button onAction="#addPart" text="Add" />
<Button onAction="#modifyPart" text="Modify" />
<Button text="Delete" />
</children>
</HBox>
</children>
</VBox>
<VBox styleClass="contentBox">
<children>
<HBox styleClass="topBox">
<HBox styleClass="subHeading">
<Label text="Products" />
</HBox>
<HBox styleClass="searchBox">
<Button text="Search" />
<TextField />
</HBox>
</HBox>
<TableView fx:id="productTable" styleClass="dataTable">
<columns>
<TableColumn text="Part ID" />
<TableColumn text="Part Name" />
<TableColumn text="Inventory Level" />
<TableColumn text="Price/Cost per Unit" />
</columns>
</TableView>
<HBox styleClass="modificationButtons">
<children>
<Button onAction="#addProduct" text="Add" />
<Button onAction="#modifyProduct" text="Modify" />
<Button text="Delete" />
</children>
</HBox>
</children>
</VBox>
</children>
</HBox>
</center>
<bottom>
<HBox fx:id="exitButton">
<children>
<Button onAction="#closeProgram" text="Exit" />
</children>
</HBox>
</bottom>
</BorderPane>
FXMLDocumentController
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package ims;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage;
/**
*
* #author chelseacamper
*/
public class FXMLDocumentController implements Initializable {
#FXML
private Label label;
#FXML
private void addPart(ActionEvent event) throws IOException {
Parent add_part_parent = FXMLLoader.load(getClass().getResource("addPart.fxml"));
Scene add_part_scene = new Scene(add_part_parent);
add_part_scene.getStylesheets().add("style.css");
Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
app_stage.setScene(add_part_scene);
app_stage.show();
}
#FXML
private void modifyPart(ActionEvent event) throws IOException {
Parent modify_part_parent = FXMLLoader.load(getClass().getResource("modifyPart.fxml"));
Scene modify_part_scene = new Scene(modify_part_parent);
modify_part_scene.getStylesheets().add("style.css");
Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
app_stage.setScene(modify_part_scene);
app_stage.show();
}
#FXML
private void addProduct(ActionEvent event) throws IOException {
Parent add_product_parent = FXMLLoader.load(getClass().getResource("addProduct.fxml"));
Scene add_product_scene = new Scene(add_product_parent);
add_product_scene.getStylesheets().add("style.css");
Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
app_stage.setScene(add_product_scene);
app_stage.show();
}
#FXML
private void modifyProduct(ActionEvent event) throws IOException {
Parent modify_product_parent = FXMLLoader.load(getClass().getResource("modifyProduct.fxml"));
Scene modify_product_scene = new Scene(modify_product_parent);
modify_product_scene.getStylesheets().add("style.css");
Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
app_stage.setScene(modify_product_scene);
app_stage.show();
}
#FXML
private void closeProgram(ActionEvent event) throws IOException {
Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
app_stage.close();
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
addPart.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane id="addPage" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ims.AddPartController">
<fx:define>
<ToggleGroup fx:id="inOutGroup" />
</fx:define>
<center>
<VBox fx:id="verticalHolding">
<children>
<HBox fx:id="topRow">
<Label text="Add Part"/>
<RadioButton fx:id="inhouse" toggleGroup="$inOutGroup" text="In-House"/>
<RadioButton fx:id="outsourced" toggleGroup="$inOutGroup" selected="true" text="Outsourced"/>
</HBox>
<HBox styleClass="fullWidth">
<HBox styleClass="halfWidthLeft">
<Label text="ID" />
</HBox>
<HBox styleClass="halfWidthRight">
<TextField promptText="Auto Gen - Disabled" />
</HBox>
</HBox>
<HBox styleClass="fullWidth">
<HBox styleClass="halfWidthLeft">
<Label text="Name" />
</HBox>
<HBox styleClass="halfWidthRight">
<TextField fx:id="partNameField" promptText="Part Name" />
</HBox>
</HBox>
<HBox styleClass="fullWidth">
<HBox styleClass="halfWidthLeft">
<Label text="Inv" />
</HBox>
<HBox styleClass="halfWidthRight">
<TextField fx:id="partInstockField" promptText="Inv" />
</HBox>
</HBox>
<HBox styleClass="fullWidth">
<HBox styleClass="halfWidthLeft">
<Label text="Price/Cost" />
</HBox>
<HBox styleClass="halfWidthRight">
<TextField fx:id="partPriceField" promptText="Price/Cost" />
</HBox>
</HBox>
<HBox styleClass="fullWidth">
<HBox styleClass="halfWidthLeft">
<Label text="Max" />
</HBox>
<HBox styleClass="halfWidthRight">
<TextField styleClass="smallTextField" fx:id="partMaxField" promptText="Max" />
<Label text="Min" />
<TextField styleClass="smallTextField" fx:id="partMinField" promptText="Min" />
</HBox>
</HBox>
<HBox styleClass="fullWidth">
<HBox styleClass="halfWidthLeft">
<Label fx:id="inhouseLabel" text="Machine ID" />
<Label fx:id="outsourcedLabel" text="Company Name" />
</HBox>
<HBox styleClass="halfWidthRight">
<TextField fx:id="inhouseTextField" promptText="Mach ID" />
<TextField fx:id="outsourcedTextField" promptText="Comp Nm" />
</HBox>
</HBox>
<HBox styleClass="fullWidth">
<HBox styleClass="halfWidthLeft">
</HBox>
<HBox styleClass="halfWidthRight">
<Button onAction="#addInhouse" text="Save" />
<Button onAction="#backToMain" text="Cancel" />
</HBox>
</HBox>
</children>
</VBox>
</center>
</BorderPane>
AddPartController
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package ims;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.stage.Stage;
/**
* FXML Controller class
*
* #author chelseacamper
*/
public class AddPartController implements Initializable {
#FXML
ToggleButton inhouse;
#FXML
ToggleButton outsourced;
#FXML
Label inhouseLabel;
#FXML
Label outsourcedLabel;
#FXML
TextField inhouseTextField;
#FXML
TextField outsourcedTextField;
#FXML
private TableView<Inhouse> partTable;
#FXML
private TextField partNameField;
#FXML
private TextField partInstockField;
#FXML
private TextField partPriceField;
#FXML
private TextField partMaxField;
#FXML
private TextField partMinField;
/**
* Initializes the controller class.
* #param url
* #param rb
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
inhouseLabel.visibleProperty().bind( inhouse.selectedProperty() );
outsourcedLabel.visibleProperty().bind( outsourced.selectedProperty() );
inhouseTextField.visibleProperty().bind( inhouse.selectedProperty() );
outsourcedTextField.visibleProperty().bind( outsourced.selectedProperty() );
inhouseLabel.managedProperty().bind( inhouse.selectedProperty() );
outsourcedLabel.managedProperty().bind( outsourced.selectedProperty() );
inhouseTextField.managedProperty().bind( inhouse.selectedProperty() );
outsourcedTextField.managedProperty().bind( outsourced.selectedProperty() );
}
#FXML
public void addInhouse(ActionEvent event){
ObservableList<Inhouse> data;
data = partTable.getItems();
data.add(new Inhouse(partNameField.getText(),
Integer.parseInt(partInstockField.getText()),
Double.parseDouble(partPriceField.getText()),
Integer.parseInt(partMaxField.getText()),
Integer.parseInt(partMinField.getText()),
Integer.parseInt(inhouseTextField.getText())
// Integer.parseInt(outsourcedTextField.getText())
));
partNameField.setText("");
partInstockField.setText(String.valueOf(partInstockField));
partPriceField.setText(String.valueOf(partPriceField));
partMaxField.setText(String.valueOf(partMaxField));
partMinField.setText(String.valueOf(partMinField));
inhouseTextField.setText(String.valueOf(inhouseTextField));
// outsourcedTextField.setText(String.valueOf(outsourcedTextField));
}
#FXML
private void backToMain(ActionEvent event) throws IOException {
Parent add_main_parent = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene add_main_scene = new Scene(add_main_parent);
add_main_scene.getStylesheets().add("style.css");
Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
app_stage.setScene(add_main_scene);
app_stage.show();
}
}
Errors that you get when you click add and then Save (don't even have to enter stuff)
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1770)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1653)
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:8390)
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:3758)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3486)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2495)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:350)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$350(GlassViewEventHandler.java:385)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$294/109927940.get(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:404)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:384)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:927)
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:497)
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:497)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1765)
... 46 more
Caused by: java.lang.NullPointerException
at ims.AddPartController.addInhouse(AddPartController.java:77)
... 56 more
The is no element in addPart.fxml with fx:id="partTable". Consequently partTable is null, and
partTable.getItems();
throws a null pointer exception.
You need to inject partTable into the controller for the FXML in which it is defined:
public class FXMLDocumentController implements Initializable {
#FXML
private Label label;
#FXML
private TableView<Inhouse> partTable ;
// ...
}
The AddPartController only needs access to the list of items associated with the table, so you can define a field for it, and a method for initializing it:
public class AddPartController implements Initializable {
// ...
private ObservableList<Inhouse> tableItems ;
public void setTableItems(ObservableList<Inhouse> tableItems) {
this.tableItems = tableItems ;
}
// ...
}
Then set the items when you load addPart.fxml:
#FXML
private void addPart(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("addPart.fxml"));
Parent add_part_parent = loader.load();
AddPartController addPartController = loader.getController();
addPartController.setTableItems(partTable.getItems());
Scene add_part_scene = new Scene(add_part_parent);
add_part_scene.getStylesheets().add("style.css");
Stage app_stage = (Stage) ((Node) event.getSource()).getScene().getWindow();
app_stage.setScene(add_part_scene);
app_stage.show();
}
and then of course you just need
#FXML
public void addInhouse(ActionEvent event){
tableItems.add(new Inhouse(partNameField.getText(),
Integer.parseInt(partInstockField.getText()),
Double.parseDouble(partPriceField.getText()),
Integer.parseInt(partMaxField.getText()),
Integer.parseInt(partMinField.getText()),
Integer.parseInt(inhouseTextField.getText())
// Integer.parseInt(outsourcedTextField.getText())
));
}
(FWIW I have no idea what
partInstockField.setText(String.valueOf(partInstockField));
etc etc is supposed to do.)

javaFX controllers doesn't communicate which each other

i have a problem with javaFX.I'm doing calculator and i divide my app between 3 FXML files(1 is a controller which controlls only numbers and operators, 2 is a controller for textfield which is result field, and last one should let them communicate which each other).
I can not manage how can i write my own method which for example put number "3" when i press number 3 in textfield-which is in other FXML and has its own fxml file.There is a nullpointer exception so i suppose im not initializing this textfield.Please help me with this problem.Is there any way to write my own method(in this example i wrote showDigit()) in MainController class - this method should set Text to textfield after pressing button - for example button 2 will put "2" in textfield.
Below I've pasted my code.
package pl.calculator.controller;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
public class MainPaneController implements Initializable {
#FXML
private TextPaneController textPaneController;
#FXML
private CalculatorPaneController calculatorPaneController;
#Override
public void initialize(URL location, ResourceBundle resources) {
/*calculatorPaneController.getButtonZero().setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
textPaneController.getTextFieldExpression().setText("example");
}
});*/ --- < THIS WORKS
}
}
FXML for MainController
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<VBox xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="pl.calculator.controller.MainPaneController">
<children>
<fx:include fx:id="textPane" source="TextPane.fxml" />
<fx:include fx:id="calculatorPane" source="CalculatorPane.fxml" />
</children>
</VBox>
Number and operation 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.TextField;
import javafx.scene.layout.GridPane;
public class CalculatorPaneController implements Initializable {
#FXML
private Button buttonFour;
#FXML
private Button buttonSix;
#FXML
private Button buttonDivide;
#FXML
private Button buttonOne;
#FXML
private Button buttonCloseBracket;
#FXML
private Button buttonDot;
#FXML
private Button buttonClear;
#FXML
private Button buttonTwo;
#FXML
private Button buttonSeven;
#FXML
private Button buttonOpenBracket;
#FXML
private Button buttonThree;
#FXML
private Button buttonMultiply;
#FXML
private Button buttonSubtract;
#FXML
private Button buttonEight;
#FXML
private Button buttonEqual;
#FXML
private Button buttonNine;
#FXML
private Button buttonZero;
#FXML
private Button buttonMemory;
#FXML
private Button buttonFive;
#FXML
private GridPane gridPane;
#FXML
private Button buttonAdd;
#FXML
private TextPaneController textPaneController;
#FXML
private CalculatorPaneController calculatorPaneController;
#Override
public void initialize(URL location, ResourceBundle resources) {
}
#FXML
private void showDigit(ActionEvent event) {
textPaneController.getTextFieldExpression().setText("s");
} <---------THIS ONE DOESNT WORK
public Button getButtonFour() {
return buttonFour;
}
public void setButtonFour(Button buttonFour) {
this.buttonFour = buttonFour;
}
public Button getButtonSix() {
return buttonSix;
}
public void setButtonSix(Button buttonSix) {
this.buttonSix = buttonSix;
}
public Button getButtonDivide() {
return buttonDivide;
}
public void setButtonDivide(Button buttonDivide) {
this.buttonDivide = buttonDivide;
}
public Button getButtonOne() {
return buttonOne;
}
public void setButtonOne(Button buttonOne) {
this.buttonOne = buttonOne;
}
public Button getButtonCloseBracket() {
return buttonCloseBracket;
}
public void setButtonCloseBracket(Button buttonCloseBracket) {
this.buttonCloseBracket = buttonCloseBracket;
}
public Button getButtonDot() {
return buttonDot;
}
public void setButtonDot(Button buttonDot) {
this.buttonDot = buttonDot;
}
public Button getButtonClear() {
return buttonClear;
}
public void setButtonClear(Button buttonClear) {
this.buttonClear = buttonClear;
}
public Button getButtonTwo() {
return buttonTwo;
}
public void setButtonTwo(Button buttonTwo) {
this.buttonTwo = buttonTwo;
}
public Button getButtonSeven() {
return buttonSeven;
}
public void setButtonSeven(Button buttonSeven) {
this.buttonSeven = buttonSeven;
}
public Button getButtonOpenBracket() {
return buttonOpenBracket;
}
public void setButtonOpenBracket(Button buttonOpenBracket) {
this.buttonOpenBracket = buttonOpenBracket;
}
public Button getButtonThree() {
return buttonThree;
}
public void setButtonThree(Button buttonThree) {
this.buttonThree = buttonThree;
}
public Button getButtonMultiply() {
return buttonMultiply;
}
public void setButtonMultiply(Button buttonMultiply) {
this.buttonMultiply = buttonMultiply;
}
public Button getButtonSubtract() {
return buttonSubtract;
}
public void setButtonSubtract(Button buttonSubtract) {
this.buttonSubtract = buttonSubtract;
}
public Button getButtonEight() {
return buttonEight;
}
public void setButtonEight(Button buttonEight) {
this.buttonEight = buttonEight;
}
public Button getButtonEqual() {
return buttonEqual;
}
public void setButtonEqual(Button buttonEqual) {
this.buttonEqual = buttonEqual;
}
public Button getButtonNine() {
return buttonNine;
}
public void setButtonNine(Button buttonNine) {
this.buttonNine = buttonNine;
}
public Button getButtonZero() {
return buttonZero;
}
public void setButtonZero(Button buttonZero) {
this.buttonZero = buttonZero;
}
public Button getButtonMemory() {
return buttonMemory;
}
public void setButtonMemory(Button buttonMemory) {
this.buttonMemory = buttonMemory;
}
public Button getButtonFive() {
return buttonFive;
}
public void setButtonFive(Button buttonFive) {
this.buttonFive = buttonFive;
}
public GridPane getGridPane() {
return gridPane;
}
public void setGridPane(GridPane gridPane) {
this.gridPane = gridPane;
}
public Button getButtonAdd() {
return buttonAdd;
}
public void setButtonAdd(Button buttonAdd) {
this.buttonAdd = buttonAdd;
}
}
FXML for operation and number controller:
<?import java.lang.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<GridPane fx:id="gridPane" prefHeight="308.0" prefWidth="375.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="pl.calculator.controller.CalculatorPaneController">
<children>
<Button fx:id="buttonOne" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" onAction="#showDigit" text="1" />
<Button fx:id="buttonFour" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="4" GridPane.rowIndex="1" />
<Button fx:id="buttonTwo" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="2" GridPane.columnIndex="1" />
<Button fx:id="buttonSeven" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="7" GridPane.rowIndex="2" />
<Button fx:id="buttonFive" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="5" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Button fx:id="buttonEight" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="8" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Button fx:id="buttonThree" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="3" GridPane.columnIndex="2" />
<Button fx:id="buttonSix" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="6" GridPane.columnIndex="2" GridPane.rowIndex="1" />
<Button fx:id="buttonNine" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="9" GridPane.columnIndex="2" GridPane.rowIndex="2" />
<Button fx:id="buttonZero" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="0" GridPane.rowIndex="3" />
<Button fx:id="buttonDot" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="." GridPane.columnIndex="1" GridPane.rowIndex="3" />
<Button fx:id="buttonEqual" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="=" GridPane.columnIndex="2" GridPane.rowIndex="3" />
<Button fx:id="buttonDivide" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="/" GridPane.columnIndex="3" GridPane.rowIndex="2" />
<Button fx:id="buttonMultiply" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="*" GridPane.columnIndex="3" GridPane.rowIndex="3" />
<Button fx:id="buttonSubtract" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="-" GridPane.columnIndex="3" GridPane.rowIndex="1" />
<Button fx:id="buttonAdd" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="+" GridPane.columnIndex="3" />
<Button fx:id="buttonCloseBracket" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text=")" GridPane.columnIndex="4" GridPane.rowIndex="3" />
<Button fx:id="buttonOpenBracket" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="(" GridPane.columnIndex="4" GridPane.rowIndex="2" />
<Button fx:id="buttonMemory" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="M" GridPane.columnIndex="4" />
<Button fx:id="buttonClear" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="C" GridPane.columnIndex="4" GridPane.rowIndex="1" />
</children>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
</GridPane>
Controller for textfields(results)
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
public class TextPaneController {
#FXML
private Label labelExpression;
#FXML
private TextField textFieldOnp;
#FXML
private Label labelOnp;
#FXML
private TextField textFieldExpression;
public Label getLabelExpression() {
return labelExpression;
}
public void setLableExpression(Label lableExpression) {
this.labelExpression = lableExpression;
}
public TextField getTextFieldOnp() {
return textFieldOnp;
}
public void setTextFieldOnp(TextField textFieldOnp) {
this.textFieldOnp = textFieldOnp;
}
public Label getLabelOnp() {
return labelOnp;
}
public void setLabelOnp(Label labelOnp) {
this.labelOnp = labelOnp;
}
public TextField getTextFieldExpression() {
return textFieldExpression;
}
public void setTextFieldExpression(TextField textFieldExpression) {
this.textFieldExpression = textFieldExpression;
}
}
FXML File for TExt:
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="89.0" prefWidth="349.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="pl.calculator.controller.TextPaneController">
<children>
<Label fx:id="lableExpression" layoutX="21.0" layoutY="14.0" text="Wprowadź wyrażenie:" />
<Label fx:id="labelOnp" layoutX="213.0" layoutY="14.0" text="Wyrażenie ONP" />
<TextField fx:id="textFieldExpression" layoutX="5.0" layoutY="45.0" />
<TextField fx:id="textFieldOnp" editable="false" layoutX="180.0" layoutY="45.0" />
</children>
</AnchorPane>
and stack trace:
TextField[id=textFieldExpression, styleClass=text-input text-field]
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(Unknown Source)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
at javafx.event.Event.fireEvent(Unknown Source)
at javafx.scene.Node.fireEvent(Unknown Source)
at javafx.scene.control.Button.fire(Unknown Source)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(Unknown Source)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
at javafx.event.Event.fireEvent(Unknown Source)
at javafx.scene.Scene$MouseHandler.process(Unknown Source)
at javafx.scene.Scene$MouseHandler.access$1800(Unknown Source)
at javafx.scene.Scene.impl_processMouseEvent(Unknown Source)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source)
at com.sun.glass.ui.View.handleMouseEvent(Unknown Source)
at com.sun.glass.ui.View.notifyMouse(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(Unknown Source)
at com.sun.glass.ui.win.WinApplication$4$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.reflect.misc.Trampoline.invoke(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
... 48 more
Caused by: java.lang.NullPointerException
at pl.calculator.controller.CalculatorPaneController.showDigit(CalculatorPaneController.java:89)
... 57 more
The FXML file CalculatorPane.fxml doesn't have an <fx:include fx:id="textPane" ... />, so the associated controller doesn't get a textPaneController injected into it. Thus textPaneController in CalculatorPaneController is null, and you get the NullPointerException.
A way to update the value from the CalculatorPaneController is to give both controllers a shared data model, and update the model. So you could do something like
public class DataModel {
private final StringProperty text = new SimpleStringProperty();
public StringProperty textProperty() {
return text ;
}
public final String getText() {
return textProperty().get();
}
public final void setText(String text) {
textProperty().set(text);
}
// other properties as needed...
}
Then you controllers can do
public class TextPaneController {
private DataModel model ;
#FXML
private TextField textFieldExpression ;
// etc ...
public void setModel(DataModel model) {
this.model = model ;
textFieldExpression.textProperty().bindBidirectional(model.textProperty());
}
}
and
public class CalculatorPaneController {
private DataModel model ;
public void setModel(DataModel model) {
this.model = model ;
}
// ...
#FXML
private void showDigit(ActionEvent event) {
model.setText("s");
}
}
Finally, you tie everything together in the main controller's initialize method:
public class MainPaneController implements Initializable {
#FXML
private TextPaneController textPaneController;
#FXML
private CalculatorPaneController calculatorPaneController;
#Override
public void initialize(URL location, ResourceBundle resources) {
DataModel model = new DataModel();
textPaneController.setModel(model);
calculatorPaneController.setModel(model);
}
}
You really don't need (and shouldn't have) all the get/set methods for the controls in the controllers. Those should be kept private and not exposed outside the controller.

JavaFX Error while navigating from 1 page to another

When I click on submit button on Login page homepage should be displayed but I get this error:
EXCEPTION
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1768)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1651)
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:204)
at javafx.scene.Node.fireEvent(Node.java:8175)
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:204)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3746)
at javafx.scene.Scene$MouseHandler.access$1800(Scene.java:3471)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1695)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2486)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:314)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:243)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:345)
at com.sun.glass.ui.View.handleMouseEvent(View.java:526)
at com.sun.glass.ui.View.notifyMouse(View.java:898)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
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:1765)
... 47 more
Caused by: java.lang.NullPointerException
at com.emo.Navigator.showLoginPage(Navigator.java:61)
at com.emo.view.LoginController.authenticate(LoginController.java:37)
... 57 more
MAIN APP
package com.emo;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import com.emo.view.HomePageController;
import com.emo.view.LoginController;
public class MainApp extends Application {
/**
* Constructor
*/
#Override
public void start(Stage primaryStage) {
Navigator nav = new Navigator();
nav.primaryStage = primaryStage;
primaryStage.setTitle("EMO APP");
nav.initRootLayout();
nav.showLoginPage();
}
public static void main(String[] args) {
launch(args);
}
}
Login Controller
package com.emo.view;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import com.emo.MainApp;
import com.emo.Navigator;
public class LoginController {
#FXML
private TextField usernameText;
#FXML
private PasswordField passwordText;
#FXML
private Label statusLabel;
int attempt = 0;
private MainApp mainApp;
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
}
/*
* #FXML void nextPane() { VistaNavigator.loadVista(VistaNavigator.VISTA_2);
* }
*/
#FXML
public void authenticate() {
if (attempt < 3) {
if (usernameText.getText().equals("abc")
&& passwordText.getText().equals("abc")) {
statusLabel.setText("");
Navigator nav = new Navigator();
nav.showLoginPage();
} else {
attempt++;
statusLabel.setText("Invalid Credentials");
}
} else {
statusLabel.setText("Your account has been locked");
}
}
}
HomePage Controller
package com.emo.view;
import javafx.fxml.FXML;
import com.emo.MainApp;
public class HomePageController {
// Reference to the main application.
private MainApp mainApp;
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
}
#FXML
public void emo() {
}
#FXML
public void cashManagement() {
}
#FXML
public void reports() {
}
#FXML
public void userProfile() {
}
#FXML
public void email() {
}
}
Navigator
package com.emo;
import java.io.IOException;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import com.emo.view.HomePageController;
import com.emo.view.LoginController;
public class Navigator {
Stage primaryStage;
BorderPane rootLayout=null;
FXMLLoader loader = new FXMLLoader();
AnchorPane pane = null;
/**
* Returns the main stage.
*
* #return
*/
public Stage getPrimaryStage() {
return primaryStage;
}
/**
* Initializes the root layout.
*/
public void initRootLayout() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class
.getResource("view/RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Shows the Login Page inside the root layout.
*/
public void showLoginPage() {
try {
// Load person overview.
loader.setLocation(MainApp.class
.getResource("view/eMO_SignIn.fxml"));
pane = (AnchorPane) loader.load();
// Set person overview into the center of root layout.
rootLayout.setCenter(pane);
// Give the controller access to the main app.
LoginController controller = loader.getController();
controller.setMainApp(new MainApp());
} catch (IOException e) {
e.printStackTrace();
}
}
public void showHomePage() {
try {
pane = null;
// Load person overview.
loader.setLocation(MainApp.class
.getResource("view/eMO_HomePage.fxml"));
pane = (AnchorPane) loader.load();
// Set person overview into the center of root layout.
rootLayout.setCenter(pane);
// Give the controller access to the main app.
HomePageController controller = loader.getController();
controller.setMainApp(new MainApp());
} catch (IOException e) {
e.printStackTrace();
}
}
}
eMO_Homepage.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="250.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.emo.view.HomePageController">
<children>
<ImageView fitHeight="49.0" fitWidth="250.0" layoutY="-2.0" pickOnBounds="true">
<image>
<Image url="#../../../../../../Desktop/thCA60O0D6.jpg" />
</image>
</ImageView>
<Label layoutX="27.0" layoutY="14.0" text="Home Page" textFill="#a12121">
<font>
<Font name="System Bold" size="12.0" />
</font>
</Label>
<ImageView fitHeight="354.0" fitWidth="250.0" layoutY="46.0" pickOnBounds="true">
<image>
<Image url="#../../../../../../Desktop/thCA7ZWC4O.jpg" />
</image>
</ImageView>
<Button layoutX="117.0" layoutY="10.0" mnemonicParsing="false" text="Sync" />
<VBox layoutX="2.0" layoutY="50.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="50.0">
<children>
<Button id="emo" layoutY="-1.0" mnemonicParsing="false" onAction="#emo" prefHeight="57.0" prefWidth="256.0" text="EMO">
<font>
<Font name="System Bold" size="12.0" />
</font>
</Button>
<Button id="cashManagement" layoutY="56.0" mnemonicParsing="false" onAction="#cashManagement" prefHeight="57.0" prefWidth="256.0" text="Cash Management">
<font>
<Font name="System Bold" size="12.0" />
</font>
</Button>
<Button id="reports" layoutY="113.0" mnemonicParsing="false" onAction="#reports" prefHeight="57.0" prefWidth="256.0" text="Reports">
<font>
<Font name="System Bold" size="12.0" />
</font>
</Button>
<Button id="userProfile" layoutY="170.0" mnemonicParsing="false" onAction="#userProfile" prefHeight="57.0" prefWidth="256.0" text="User Profile">
<font>
<Font name="System Bold" size="12.0" />
</font>
</Button>
<Button id="email" layoutY="227.0" mnemonicParsing="false" onAction="#email" prefHeight="57.0" prefWidth="256.0" text="Email">
<font>
<Font name="System Bold" size="12.0" />
</font>
</Button>
</children>
</VBox>
</children>
</AnchorPane>
eMO_SignIn.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="250.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.emo.view.LoginController">
<children>
<ImageView fitHeight="49.0" fitWidth="250.0" layoutY="-2.0" pickOnBounds="true">
<image>
<Image url="#../../../../Images/Grey.jpg" />
</image>
</ImageView>
<Label layoutX="27.0" layoutY="14.0" text="Sign In" textFill="#a12121">
<font>
<Font name="System Bold" size="12.0" />
</font>
</Label>
<ImageView fitHeight="354.0" fitWidth="250.0" layoutY="46.0" pickOnBounds="true">
<image>
<Image url="#../../../../Images/Red.jpg" />
</image>
</ImageView>
<VBox layoutX="27.0" layoutY="79.0" spacing="5.0" AnchorPane.leftAnchor="15.0">
<children>
<Label layoutX="27.0" layoutY="79.0" text="Username:-*" textFill="#f8e4e4">
<font>
<Font name="System Bold" size="12.0" />
</font>
</Label>
<TextField fx:id="usernameText" layoutX="27.0" layoutY="105.0" prefHeight="42.0" prefWidth="150.0" />
<Label layoutX="28.0" layoutY="148.0" text="Password:-*" textFill="#f8e4e4">
<font>
<Font name="System Bold" size="12.0" />
</font>
</Label>
<PasswordField fx:id="passwordText" layoutX="28.0" layoutY="174.0" prefHeight="42.0" prefWidth="150.0" />
</children>
</VBox>
<Button layoutX="125.0" layoutY="236.0" mnemonicParsing="false" onAction="#authenticate" prefHeight="25.0" prefWidth="68.0" text="Sign In" AnchorPane.leftAnchor="100.0" AnchorPane.rightAnchor="82.0">
<font>
<Font name="System Bold" size="12.0" />
</font>
</Button>
<Label fx:id="statusLabel" alignment="CENTER" layoutX="46.0" layoutY="294.0" prefHeight="17.0" prefWidth="164.0" AnchorPane.bottomAnchor="100.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="280.0" />
</children>
</AnchorPane>
RootLayout.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 prefHeight="400.0" prefWidth="600.0"
xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
<top>
<MenuBar BorderPane.alignment="CENTER">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Delete" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About" />
</items>
</Menu>
</menus>
</MenuBar>
</top>
</BorderPane>
In LoginController.authenticate(), you do:
Navigator nav = new Navigator();
nav.showLoginPage();
and in Navigator.showLoginPage() you have:
pane = loader.load();
rootLayout.setCenter(pane);
However, at no point was rootLayout initialized for this Navigator instance, so you get the NullPointerException as shown in the stack trace.
One possible fix would be to give the LoginController a reference to the Navigator you have already created (and properly initialized), so it doesn't have to create a new one:
public class LoginController {
private Navigator navigator ;
public void setNavigator(navigator) {
this.navigator = navigator ;
}
// everything else as before...
#FXML
public void authenticate() {
if (attempt < 3) {
if (usernameText.getText().equals("abc")
&& passwordText.getText().equals("abc")) {
statusLabel.setText("");
navigator.showLoginPage();
} else {
attempt++;
statusLabel.setText("Invalid Credentials");
}
} else {
statusLabel.setText("Your account has been locked");
}
}
}
and then
public class Navigator {
// everything else as before....
public void showLoginPage() {
try {
// Load person overview.
loader.setLocation(MainApp.class
.getResource("view/eMO_SignIn.fxml"));
pane = (AnchorPane) loader.load();
// Set person overview into the center of root layout.
rootLayout.setCenter(pane);
// Give the controller access to the main app.
LoginController controller = loader.getController();
controller.setMainApp(new MainApp());
// Give the controller access to this navigator:
controller.setNavigator(this);
} catch (IOException e) {
e.printStackTrace();
}
}
}

Resources