0

好的,所以我有一个难题。我有一个 Qaurtz Cron,我想用它来安排和运行一些 Java 测试。这些任务是通过使用 JavaFX 的 gui 安排的。但是,作业本身会调用运行测试方法。这项工作迫使我将某些元素设为静态,但通过将它们设为静态,我得到一个空指针异常。我真的很感激这里的一些帮助。

所以这里是强制事物是静态的工作类。

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);

请注意,runScheduledTests() 方法会进行一些配置并调用 runTest 方法。在运行测试方法内部是我遇到错误的地方,特别是这一行:

if (IEbutton.isSelected()) {
                BrowserConfig.setDriver(Browsers.IE());
            } else {
                BrowserConfig.setDriver(Browsers.Chrome());
            }

原因是上面我有这个:

@FXML
    public static RadioButton ChromeButton;

    @FXML
    public static RadioButton IEbutton;

正如我所说,这有点问题,如果我不让它们成为静态的,那么工作类会因为我进行非静态引用而大喊大叫。

我该如何解决这个冲突?

4

2 回答 2

1

TL;DR:您不应该在使用@FXML 注释的字段上使用静态。

有关更多信息,请查看 - javafx 8 兼容性问题 - FXML 静态字段

您可以使用 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();
        }
    }
}
于 2016-11-24T19:26:13.267 回答
0

问题是当控制器本身不是静态的时,您正在尝试使用静态。考虑到我建议在此处查看静态和非静态之间的区别。关于修复您的代码。首先制作你的按钮ChromeButton,而IEbutton不是静态的。然后当你的应用程序类,是这样的:

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.
    }
}

然后将按钮或控制器的引用作为变量传递给 Job 类。像这样:

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();
        }
    }
}

您的问题的核心是控制器变量不能是静态的,因为控制器依赖于实例化类并传递所需的信息。解决此问题的最佳方法是通过使用变量传递对按钮或类的引用构造函数。请阅读我发送给您的链接,以便更好地了解静态和非静态。此外,如果您对构造函数感到困惑,也请查看此处

于 2016-11-24T19:00:31.903 回答