java.lang.NullPointerException 用于 JavaFX 中带有静态引用的静态按钮
java.lang.NullPointerException for static button in JavaFX with static reference
好吧,我有点困惑。我有一个 Qaurtz Cron,我想用它来安排和 运行 一些 Java 测试。这些任务是通过使用 JavaFX 的图形用户界面安排的。但是,作业本身会调用 运行 测试方法。这项工作迫使我将某些元素设为静态,但通过将它们设为静态,我得到了一个空指针异常。我真的很感激这里的一些帮助。
所以这是强制事物保持静态的工作 class。
public class newJob implements Job{
public void execute(JobExecutionContext arg0) throws JobExecutionException {
System.out.println("We are attempting the job now");
try {
FXMLDocumentController.runScheduledTests();
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
在我的控制器中,我有这样的东西:
public static void runTests() throws SQLException, IOException {
// Set running to true. In current form we do not use this bool,
// however, we may
// make changes that rely on this.
running = true;
FileOutputStream fos = null;
// Verify that users exist, and there is a url with the word max in it
int count = DBHelpers.getResults("SELECT * FROM USERS;", new String[] { "ID" }).length();
// Verify that we have both users and a maximo url to work with.
if ((!userList.isEmpty() || count > 0) && userMaxListChoice.length() > 5) {
// Set the proper driver, default to chrome if none is selected
if (IEbutton.isSelected()) {
BrowserConfig.setDriver(Browsers.IE());
} else {
BrowserConfig.setDriver(Browsers.Chrome());
}
// Let's assign maximo. If no one has clicked the use UserList
// button, assume that the data inside
// maximo name is good to use
if (userMaxListChoice != null) {
BrowserConfig.setMaximo(userMaxListChoice);
// System.out.println("used maxLIst choice");
} else {
// If the user has not selected a name from the maximo list,
// let's grab whatever
// they have entered in the maximoName field.
BrowserConfig.setMaximo(maximoName.getText());
}
// Set the system pause based on the interval string
int pause = Integer.parseInt(interval.getText().toString());
// Make sure the puase is in miliseconds
pause = pause * 1000;
BrowserConfig.setInterval(pause);
请注意,运行ScheduledTests() 方法会进行一些配置并调用 运行Test 方法。在 运行 测试方法中,我特别遇到了这一行的错误:
if (IEbutton.isSelected()) {
BrowserConfig.setDriver(Browsers.IE());
} else {
BrowserConfig.setDriver(Browsers.Chrome());
}
原因是上面我有这个:
@FXML
public static RadioButton ChromeButton;
@FXML
public static RadioButton IEbutton;
正如我所说,这有点问题,如果我不将它们设为静态,工作 class 会因为我制作非静态引用而对我大喊大叫。
我该如何解决这个冲突?
问题是当控制器本身不是静态时,您正试图使用静态。考虑到我建议看一下静态和非静态之间的区别 here。关于修复代码。首先让你的按钮 ChromeButton
和 IEbutton
不是静态的。然后当你的应用程序 class,像这样:
public class HelloWorld extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
//pass a reference of your stage to job.
}
}
然后将按钮或控制器的引用作为变量传递到作业中 class。像这样:
public class newJob implements Job{
private RadioButton chrome;
private RadioButton ie;
public newJob(RadioButton chrome, RadioButton ie) {
this.chrome = chrome;
this.ie = ie;
}
public void execute(JobExecutionContext arg0) throws JobExecutionException {
System.out.println("We are attempting the job now");
try {
FXMLDocumentController.runScheduledTests();
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
你的问题的核心是控制器变量不能是静态的,因为控制器依赖于实例化class并传递所需的信息。最好的方法通过在构造函数中使用变量将引用传递给按钮或 class 来解决此问题。请阅读我发给您的 link 以更好地理解静态和非静态。另外,如果您对构造函数感到困惑,请也看看 here。
TL;DR :您不应在使用 @FXML 注释的字段上使用静态。
有关更多信息,请查看 - javafx 8 compatibility issues - FXML static fields
您可以使用 FXMLLoader 加载 FXML,然后从中获取控制器的实例。通过这样做,您可以将方法 runScheduledTests()
转换为非静态方法。
public class newJob implements Job{
public void execute(JobExecutionContext arg0) throws JobExecutionException {
try {
FXMLLoader fxmlLoader =
new FXMLLoader(getClass().getResource("path-to-fxml.fxml"));
fxmlLoader.load();
FXMLDocumentController fxmlDocumentController =
(FXMLDocumentController)fxmlLoader.getController();
fxmlDocumentController.runScheduledTests(); // convert the method to non-static
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
好吧,我有点困惑。我有一个 Qaurtz Cron,我想用它来安排和 运行 一些 Java 测试。这些任务是通过使用 JavaFX 的图形用户界面安排的。但是,作业本身会调用 运行 测试方法。这项工作迫使我将某些元素设为静态,但通过将它们设为静态,我得到了一个空指针异常。我真的很感激这里的一些帮助。
所以这是强制事物保持静态的工作 class。
public class newJob implements Job{
public void execute(JobExecutionContext arg0) throws JobExecutionException {
System.out.println("We are attempting the job now");
try {
FXMLDocumentController.runScheduledTests();
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
在我的控制器中,我有这样的东西:
public static void runTests() throws SQLException, IOException {
// Set running to true. In current form we do not use this bool,
// however, we may
// make changes that rely on this.
running = true;
FileOutputStream fos = null;
// Verify that users exist, and there is a url with the word max in it
int count = DBHelpers.getResults("SELECT * FROM USERS;", new String[] { "ID" }).length();
// Verify that we have both users and a maximo url to work with.
if ((!userList.isEmpty() || count > 0) && userMaxListChoice.length() > 5) {
// Set the proper driver, default to chrome if none is selected
if (IEbutton.isSelected()) {
BrowserConfig.setDriver(Browsers.IE());
} else {
BrowserConfig.setDriver(Browsers.Chrome());
}
// Let's assign maximo. If no one has clicked the use UserList
// button, assume that the data inside
// maximo name is good to use
if (userMaxListChoice != null) {
BrowserConfig.setMaximo(userMaxListChoice);
// System.out.println("used maxLIst choice");
} else {
// If the user has not selected a name from the maximo list,
// let's grab whatever
// they have entered in the maximoName field.
BrowserConfig.setMaximo(maximoName.getText());
}
// Set the system pause based on the interval string
int pause = Integer.parseInt(interval.getText().toString());
// Make sure the puase is in miliseconds
pause = pause * 1000;
BrowserConfig.setInterval(pause);
请注意,运行ScheduledTests() 方法会进行一些配置并调用 运行Test 方法。在 运行 测试方法中,我特别遇到了这一行的错误:
if (IEbutton.isSelected()) {
BrowserConfig.setDriver(Browsers.IE());
} else {
BrowserConfig.setDriver(Browsers.Chrome());
}
原因是上面我有这个:
@FXML
public static RadioButton ChromeButton;
@FXML
public static RadioButton IEbutton;
正如我所说,这有点问题,如果我不将它们设为静态,工作 class 会因为我制作非静态引用而对我大喊大叫。
我该如何解决这个冲突?
问题是当控制器本身不是静态时,您正试图使用静态。考虑到我建议看一下静态和非静态之间的区别 here。关于修复代码。首先让你的按钮 ChromeButton
和 IEbutton
不是静态的。然后当你的应用程序 class,像这样:
public class HelloWorld extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
//pass a reference of your stage to job.
}
}
然后将按钮或控制器的引用作为变量传递到作业中 class。像这样:
public class newJob implements Job{
private RadioButton chrome;
private RadioButton ie;
public newJob(RadioButton chrome, RadioButton ie) {
this.chrome = chrome;
this.ie = ie;
}
public void execute(JobExecutionContext arg0) throws JobExecutionException {
System.out.println("We are attempting the job now");
try {
FXMLDocumentController.runScheduledTests();
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
你的问题的核心是控制器变量不能是静态的,因为控制器依赖于实例化class并传递所需的信息。最好的方法通过在构造函数中使用变量将引用传递给按钮或 class 来解决此问题。请阅读我发给您的 link 以更好地理解静态和非静态。另外,如果您对构造函数感到困惑,请也看看 here。
TL;DR :您不应在使用 @FXML 注释的字段上使用静态。
有关更多信息,请查看 - javafx 8 compatibility issues - FXML static fields
您可以使用 FXMLLoader 加载 FXML,然后从中获取控制器的实例。通过这样做,您可以将方法 runScheduledTests()
转换为非静态方法。
public class newJob implements Job{
public void execute(JobExecutionContext arg0) throws JobExecutionException {
try {
FXMLLoader fxmlLoader =
new FXMLLoader(getClass().getResource("path-to-fxml.fxml"));
fxmlLoader.load();
FXMLDocumentController fxmlDocumentController =
(FXMLDocumentController)fxmlLoader.getController();
fxmlDocumentController.runScheduledTests(); // convert the method to non-static
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}