java.lang.NullPointerException in handling with FXML inside another FXML in Javafx - nullpointerexception

I have been trying to figure out how to deal with a FXML file in another FXML file. But I have an exception. :(
This is my inner FXML (NewInside.fxml in view package):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="305.0" prefWidth="360.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="controller.NewInsideController">
<children>
<Button fx:id="newBtn" layoutX="30.0" layoutY="202.0" mnemonicParsing="false" onAction="#btnClick" text="Button" />
<TextField fx:id="newTxt" layoutX="30.0" layoutY="134.0" prefHeight="25.0" prefWidth="280.0" />
<Label fx:id="newLbl" layoutX="30.0" layoutY="62.0" prefHeight="17.0" prefWidth="280.0" />
</children>
</AnchorPane>
This is its controller (NewInsideController.java in controller package):
package controller;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
public class NewInsideController implements Initializable{
#FXML public static Label newLbl;
#FXML public static TextField newTxt;
#FXML public static Button newBtn;
#Override
public void initialize(URL location, ResourceBundle resources) {
}
#FXML
private void btnClick(ActionEvent e){
System.out.println("Button is clicked!");
newLbl.setText(newTxt.getText());
}
}
And this is outer FXML (New.fxml in view package):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="380.0" prefWidth="529.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="controller.NewController">
<children>
<fx:include source="NewInside.fxml" />
</children>
</AnchorPane>
This is its controller (NewController.java in controller package):
package controller;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.Initializable;
public class NewController implements Initializable {
/*#FXML private Label newLbl;
#FXML private Button newBtn;
#FXML private TextField newTxt;
*/
#Override
public void initialize(URL location, ResourceBundle resources) {
}
/*#FXML
public void btnClick(ActionEvent e){
newLbl.setText(newTxt.getText());
}*/
}
Finally, this is the Main.java in application package:
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("/view/New.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
When I clicked the button, it gives me very long exception:
"Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException....
.....
Caused by: java.lang.NullPointerException
at controller.NewInsideController.btnClick(NewInsideController.java:27)
... 57 more"
Please help me! :(

As #Inge suggests, using the static field is not the right way to do it. Also, instead of public, you should use private. If you need to expose your controls, use their properties.
You can read why here:
You should not use a static field here
... don't use static fields
Just change this in your NewInsideController:
#FXML private Label newLbl;
#FXML private TextField newTxt;
#FXML private Button newBtn;
EDIT
If you want to have access to your controls from other classes, instead of adding getters/setters to expose directly the controls, it is better just exposing their properties.
For instance, to have access to the text of these controls you could add:
public StringProperty newLblText() {
return newLbl.textProperty();
}
public StringProperty newTxtText() {
return newTxt.textProperty();
}
public StringProperty newBtnText() {
return newBtn.textProperty();
}
This will allow you binding (or listening to changes), getting/setting the text property from any of them from the outside of your controller.
To get a valid instance of NewInsideController from NewController, follow this link. First modify New.fxml:
<fx:include fx:id="newInside" source="NewInside.fxml" />
and now you can get an instance, and add some listeners with those properties:
public class NewController implements Initializable {
#FXML
private Parent newInside;
#FXML
private NewInsideController newInsideController;
#Override
public void initialize(URL url, ResourceBundle rb) {
newInsideController.newBtnText().addListener(
(obs,s,s1)->System.out.println("nweBtn Text;" +s1));
if(newInsideController.newLblText().get().isEmpty()){
newInsideController.newLblText().set("Text for the textfield");
}
newInsideController.newTxtText().addListener(
(obs,s,s1)->System.out.println("s1 "+s1));
}
}

Related

java.lang.ClassCastException error when implementing extent reporting in TestNG XML file

I getting an error telling java.lang.ClassCastException: [My extent report class name] cannot be cast to org.testng.ITestNGListener when running the TestNG XML file as a Test suite.
I have automated a web page using page factory design technique using MAVEN and TestNG which consists of 6 page classes objects initialize in one package. I also written extent report listener class in another package. In addition to this I also has a base class in another package which is the super class of all 6 page object initialize classes. I have written test cases for 3 page classes and base class is the super class of these classes as well.
I have generated TestNG XML file by adding all 3 page test cases and adding extent report class as a listener for this XML file.
I will show the structure of my framework by including one class from each package below.
Page object initialize package - Login class
package com.crm.qa.pages;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import com.crm.qa.base.TestBase;
import com.crm.qa.util.TestUtil;
public class LoginPage extends TestBase {
#FindBy(name="username")
WebElement userName;
#FindBy(name="password")
WebElement password;
#FindBy(xpath="//input[#type='submit']")
WebElement loginBtn;
#FindBy(xpath="//button[contains(text(),'Sign Up')]")
WebElement signupBtn;
#FindBy(xpath="//img[#class = 'img-responsive']")
WebElement crmLogo;
//Initializing the page objects
public LoginPage() {
PageFactory.initElements(driver, this);
}
public String validateLoginPageTitle() {
return driver.getTitle();
}
public boolean validateCRMLogo() {
return crmLogo.isDisplayed();
}
public HomePage login (String un, String pwd) {
userName.sendKeys(un);
password.sendKeys(pwd);
loginBtn.submit();
driver.manage().timeouts().pageLoadTimeout(TestUtil.PAGE_LOAD_TIMEOUT, TimeUnit.SECONDS);
// Actions act = new Actions(driver);
// act.moveToElement(loginBtn).click().build().perform();
return new HomePage();
}
}
Base Package - Test Base class
package com.crm.qa.base;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.events.EventFiringWebDriver;
import com.crm.qa.util.TestUtil;
import com.crm.qa.util.WebEventListener;
public class TestBase {
public static WebDriver driver;
public static Properties prop;
public static EventFiringWebDriver e_driver;
public static WebEventListener eventListener;
public TestBase() {
try {
prop = new Properties();
FileInputStream ip = new FileInputStream("C:\\Users\\i7\\git\\TestDesignFramework1\\Suresh.com.automationLearning\\src"
+ "\\main\\java\\com\\crm\\qa\\config\\config.properties");
prop.load(ip);
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
public static void initialization () {
String browserName = prop.getProperty("browser");
if(browserName.equals("chrome")) {
System.setProperty("webdriver.chrome.driver", "E:\\C\\Selenium\\Chrome Driver\\Extract\\chromedriver.exe");
driver = new ChromeDriver();
}
else if (browserName.equals("firefox")) {
System.setProperty("webdriver.gecko.driver", "E:\\C\\Selenium\\GeckoDriver\\Extract\\geckodriver.exe");
driver = new FirefoxDriver();
}
e_driver = new EventFiringWebDriver(driver);
eventListener = new WebEventListener();
e_driver.register(eventListener);
driver = e_driver;
driver.manage().window().maximize();
driver.manage().deleteAllCookies();
driver.get(prop.getProperty("url"));
driver.manage().timeouts().pageLoadTimeout(TestUtil.PAGE_LOAD_TIMEOUT, TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(TestUtil.IMPLICIT_WAIT, TimeUnit.SECONDS);
}
}
Test cases package - Login page test class
package com.crm.qa.pages.testcases;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeMethod;
import org.testng.Assert;
import com.crm.qa.base.TestBase;
import com.crm.qa.pages.HomePage;
import com.crm.qa.pages.LoginPage;
public class LoginPageTest extends TestBase {
LoginPage loginPage;
HomePage homepage;
public LoginPageTest() {
super();
}
#BeforeMethod
public void setUp() {
initialization();
loginPage = new LoginPage();
}
#Test(priority = 1)
public void loginPageTitle() {
// extentTest = extent.createTest("loginPageTitle");
String title = loginPage.validateLoginPageTitle();
Assert.assertEquals(title, "#1 Free CRM software in the "
+ "cloud for sales and service");
}
#Test(priority = 2)
public void crmLogoImageTest() {
// extentTest = extent.createTest("crmLogoImageTest");
boolean flag = loginPage.validateCRMLogo();
Assert.assertTrue(flag);
}
#Test(priority = 3)
public void loginTest() {
// extentTest = extent.createTest("loginTest");
homepage = loginPage.login(prop.getProperty("username"), prop.getProperty("password"));
System.out.println("Successfully login to the home page of freeCRM");
}
#AfterMethod
public void tearDown() {
driver.quit();
}
}
Test Util package - Extent report listener class
package com.crm.qa.ExtentReport;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.markuputils.ExtentColor;
import com.aventstack.extentreports.markuputils.MarkupHelper;
import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
public class ExtentReportListener {
public static ExtentHtmlReporter htmlReporter;
public static ExtentReports extent;
public static ExtentTest extentTest;
#BeforeSuite
public void setUp() {
htmlReporter = new ExtentHtmlReporter("C:\\Users\\i7\\git\\TestDesignFramework1\\Suresh.com.automationLearning\\Reporting\\ExtentReporting.html");
extent = new ExtentReports();
extent.attachReporter(htmlReporter);
}
#AfterMethod
public void getResult(ITestResult result) {
if (result.getStatus()==ITestResult.FAILURE) {
extentTest.fail(MarkupHelper.createLabel(result.getName()+" Test Case Failed", ExtentColor.RED));
extentTest.fail(result.getThrowable());
}
else if (result.getStatus()==ITestResult.SUCCESS) {
extentTest.pass(MarkupHelper.createLabel(result.getName()+" Test Case Passed", ExtentColor.GREEN));
extentTest.pass(result.getThrowable());
}
else {
extentTest.skip(MarkupHelper.createLabel(result.getName()+" Test Case Skipped", ExtentColor.ORANGE));
extentTest.skip(result.getThrowable());
}
}
#AfterSuite
public void tearDown() {
extent.flush();
}
}
TestNG XML file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Free CRM Test Application Regression Test Suite">
<listeners>
<listener class-name="com.crm.qa.ExtentReport.ExtentReportListener">
</listener>
</listeners>
<test thread-count="5" name="Free CRM app regression test cases">
<classes>
<class name="com.crm.qa.pages.testcases.LoginPageTest"/>
<class name="com.crm.qa.pages.testcases.HomePageTest"/>
<class name="com.crm.qa.pages.testcases.ContactsPageTest"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
TestNG is working as designed.
Whenever you add an entry such as the one below, into your testng suite xml file
<listeners>
<listener class-name="com.crm.qa.ExtentReport.ExtentReportListener"/>
</listeners>
TestNG expects that the class implements one of the sub-interfaces of org.testng.ITestNGListener
Your class doesn't do that, which is what is triggering the exception.
Please go through the relevant extent reports documentation to understand how to correctly work with extent reports.
The solution is to use "implements IReporter" inside testNG Report class.
In your case the testNG reporting class is "ExtentReportListener" so you have to type:
public class FinalReport implements IReporter
{}

Automatic Click Button For Android

I'm new in Android Development. I reviewed the automatic click button post before but I still cannot configure the these error. The App Stop Working after 5 secs timer.
Below is my code on MainActivity:
package com.example.cynog.autobutton;
import android.content.Intent;
import android.content.res.Resources;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
private Button button1;
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
performClick();
Thread timer = new Thread(){
public void run(){
try{
sleep(5000);
} catch (InterruptedException e){
e.printStackTrace();
}finally{
button1.performClick();
}
}
};
timer.start();
} catch (Resources.NotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void performClick() {
button1 = (Button) findViewById(R.id.button);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this, activity.class);
startActivity(i);
}
});
}
}
And This is my XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.cynog.autobutton.MainActivity">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:onClick="performClick"
tools:layout_editor_absoluteX="153dp"
tools:layout_editor_absoluteY="209dp" />
</android.support.constraint.ConstraintLayout>
Button is created in the ui thread that is main thread.
so if u want to make any action with it do it inside handler.post(new Runnable(){void run(){//perform action here}. make a Handler object in oncreate(). Handler handler=new Handler().
and put the handler.post() code in the timer thread run method after sleep. I hope it works.

NullPointerException: Attempt to invoke virtual method 'void io.realm.Realm.beginTransaction()' on a null object reference

So I am making an app where I use an activity to introduce data about cities using Realm. I want to save the data when the floating action button is pressed but I keep getting a NullPointerExeption and when I debbug the app I see that realm in realm.beginTransaction() is null..
Can someone give an advice on why this happens? Thank you!
City class:
package com.android.bianca.cityworld2.models;
import com.android.bianca.cityworld2.app.MyApplication;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import io.realm.annotations.Required;
/**
* Created by Bianca on 25/01/2017.
*/
public class City extends RealmObject {
#PrimaryKey
private int id;
#Required
private String nombre;
#Required
private String description;
#Required
private String imagen;
public City(){
};
public City(String nombre, String description, String imagen) {
this.id = MyApplication.CityID.incrementAndGet();
this.nombre = nombre;
this.description = description;
this.imagen = imagen;
}
public int getID(){ return id;}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getImagen() {
return imagen;
}
public void setImagen(String imagen) {
this.imagen = imagen;
}
}
AddEditActivity:
package com.android.bianca.cityworld2.activities;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.android.bianca.cityworld2.R;
import com.android.bianca.cityworld2.models.City;
import com.squareup.picasso.Picasso;
import io.realm.Realm;
public class AddEditActivity extends AppCompatActivity {
private FloatingActionButton fabSave;
private Realm realm;
private TextView textViewNombre;
private TextView textViewDescription;
private ImageView imageViewImagen;
private TextView textViewUrlFoto;
private ImageView imageViewPreview;
private City ciudadNueva;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_edit);
Realm.init(getApplicationContext());
Realm realm = Realm.getDefaultInstance();
bindReferences();
imageViewPreview.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String imageURL = textViewUrlFoto.getText().toString();
if(imageURL.equals("")) {
Toast.makeText(AddEditActivity.this, "No has introducido ningun url", Toast.LENGTH_SHORT).show();
}else {
Picasso.with(AddEditActivity.this).load(imageURL).error(R.mipmap.ic_star).fit().into(imageViewImagen);
}
}
});
fabSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
crearNuevaCiudad();
}
});
}
private void crearNuevaCiudad(){
String nombre = textViewNombre.getText().toString().trim();
String desc = textViewDescription.getText().toString().trim();
String img = textViewUrlFoto.getText().toString().trim();
ciudadNueva = new City(nombre,desc,img);
realm.beginTransaction();
realm.copyToRealm(ciudadNueva);
realm.commitTransaction();
//<Toast.makeText(AddEditActivity.this, nombre + "|"+description+"|"+img, Toast.LENGTH_SHORT).show();
}
private void bindReferences(){
fabSave = (FloatingActionButton) findViewById(R.id.fabSave);
textViewNombre =(TextView) findViewById(R.id.editTextEditAddNombre);
textViewDescription =(TextView) findViewById(R.id.editTextAddEditDescription);
textViewUrlFoto =(TextView) findViewById(R.id.editTextEditAddUrl);
imageViewImagen = (ImageView) findViewById(R.id.imageViewEditAddBackground);
imageViewPreview = (ImageView) findViewById(R.id.imageViewEditAddPreview);
}
}
MyApplication:
package com.android.bianca.cityworld2.app;
import android.app.Application;
import com.android.bianca.cityworld2.models.City;
import java.util.concurrent.atomic.AtomicInteger;
import io.realm.Realm;
import io.realm.RealmConfiguration;
import io.realm.RealmObject;
import io.realm.RealmResults;
/**
* Created by Bianca on 26/01/2017.
*/
public class MyApplication extends Application {
public static AtomicInteger CityID = new AtomicInteger();
#Override
public void onCreate() {
setUpRealmConfig();
Realm realm = Realm.getDefaultInstance();
CityID = getIdByTable(realm, City.class);
realm.close();
}
private void setUpRealmConfig() {
Realm.init(this);
RealmConfiguration config = new RealmConfiguration.Builder().deleteRealmIfMigrationNeeded().build();
Realm.setDefaultConfiguration(config);
}
private <T extends RealmObject> AtomicInteger getIdByTable(Realm realm, Class<T> anyClass) {
RealmResults<T> results = realm.where(anyClass).findAll();
return (results.size() > 0) ? new AtomicInteger(results.max("id").intValue()) : new AtomicInteger();
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.bianca.cityworld2">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".activities.MainActivity">
</activity>
<activity android:name=".activities.AddEditActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

while running robotium error messge has been displayed "does not have a signature matching the target com.android.calculator2"

Here is my code
package com.test.android.calculator2;
import android.app.Activity;
import com.robotium.solo.Solo;
import android.test.ActivityInstrumentationTestCase2;
#SuppressWarnings("unchecked")
public class TestApk extends ActivityInstrumentationTestCase2 {
private static final String TARGET_PACKAGE_ID="com.android.calculator2";
private static final String
LAUNCHER_ACTIVITY_FULL_CLASSNAME="com.android.calculator2.Calculator";
private static Class <?> launcherActivityClass;
static {
try {
Activity act = new Activity();
launcherActivityClass = Class.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
// #SuppressWarnings("unchecked")
public TestApk()throws ClassNotFoundException {
super(TARGET_PACKAGE_ID,launcherActivityClass);
}
private Solo solo;
#Override
protected void setUp() throws Exception {
solo = new Solo(getInstrumentation());
}
public void testCanOpenSettings() {
solo.getActivityMonitor();
getActivity();
solo.sendKey(Solo.DOWN);
solo.goBack();
}
#Override
public void tearDown() throws Exception {
try {
solo.finalize();
} catch (Throwable e) {
e.printStackTrace();
}
getActivity().finish();
super.tearDown();
}
}
Manifest file like this
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.android.calculator2"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="19" />
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.android.calculator2" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<uses-library android:name="android.test.runner" />
</application>
</manifest>
It looks like your defined target package com.android.calculator2 could not be found.
I see that the class you posted is located in the package com.test.android.calculator2
You either have to create a new package com.android.calculator2 or set your target package to a existing package (e.g. com.test.android.calculator2).

NPE in JavaFX when call the field in controller

I want to make my undecorated scene draggable. My root layout contain toolbar with controls and content. I gave id for toolbar and set controller for .fxml layout.
Then i do all steps like in Dragging an undecorated Stage in JavaFX
But i have null pointer, when try to call EffectUtilities.makeDraggable(stage, tool_bar);
Here is the code:
Main
public class UpdaterMain extends Application{
private Stage primaryStage;
private BorderPane rootLayout;
#Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
this.primaryStage.initStyle(StageStyle.UNDECORATED);
this.primaryStage.initStyle(StageStyle.TRANSPARENT);
initRootLayout();
showContentOverview();
}
/**
* Initializes the root layout.
*/
public void initRootLayout() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(UpdaterMain.class.getResource("RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
UpdaterMainController controller =
loader.getController();
controller.registerStage(primaryStage); <<--Here is NPE
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Shows main content
*/
public void showContentOverview() {
try {
// Load person overview.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(UpdaterMain.class.getResource("updater-layout.fxml"));
SplitPane contentOverview = loader.load();
// Set person overview into the center of root layout.
rootLayout.setCenter(contentOverview);
} catch (IOException e) {
e.printStackTrace();
}
}
public Stage getPrimaryStage() {
return primaryStage;
}
public static void main(String[] args) {
launch(args);
}
}
Controller
import com.iminegination.utils.EffectUtilities;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ToolBar;
import javafx.stage.Stage;
public class UpdaterMainController {
#FXML
private ToolBar tool_bar;
public void registerStage(Stage stage) {
EffectUtilities.makeDraggable(stage, tool_bar); <<--Here is NPE (tool_bar is null, but why?)
}
public UpdaterMainController() {
}
}
layout.fxml
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="690.0" prefWidth="1024.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.iminegination.updater.view.UpdaterMainController">
<top>
<ToolBar id="tool_bar" nodeOrientation="RIGHT_TO_LEFT" prefHeight="40.0" prefWidth="200.0">
<items>
<Button id="exitButton" mnemonicParsing="false" text="X" onAction="#click"/>
<Button mnemonicParsing="false" text="Settings" />
<Button mnemonicParsing="false" text="_" />
</items>
</ToolBar>
</top>
</BorderPane>
You need to define an fx:id attribute for your controls in FXML.
In your FXML you have:
<ToolBar id="tool_bar" . . .
You should have:
<ToolBar id="tool_bar" fx:id="tool_bar" . . .
id defines the CSS id.
fx:id defines the link between the FXML and the controller variable names.