Java 为什么可以';我不能在按钮事件下使用setText()?

Java 为什么可以';我不能在按钮事件下使用setText()?,java,javafx,Java,Javafx,所以我将我的复杂控制台程序重新设计成GUI。然而,我是一个非常没有经验的JavaFX用户 Label cityNameLabel = (Label) scene.lookup("#cityNameLabel"); cityNameLabel.setText("No text"); Button startButton = (Button) scene.lookup("#startButton"); 在这里,我成功启动了我的标签。此时,我仍然可以使用citynamelab.setText();

所以我将我的复杂控制台程序重新设计成GUI。然而,我是一个非常没有经验的JavaFX用户

Label cityNameLabel = (Label) scene.lookup("#cityNameLabel");
cityNameLabel.setText("No text");

Button startButton = (Button) scene.lookup("#startButton");
在这里,我成功启动了我的标签。此时,我仍然可以使用citynamelab.setText();它会起作用的

这继续:

startButton.setOnAction(e -> {
    String enteredUrl = linkField.getText();
    if(isValidUrl(enteredUrl)) {
        try {
            cityNameLabel.setText("Test");
            doJob(enteredUrl, cityNameLabel);
        } catch (IOException e1) {
            e1.printStackTrace();
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
    }.........
当我尝试在这里更改标签时,它不会发生。我实际上需要做的是将cityNamelLabel引用到doJob()方法,我希望doJob()方法对其进行更改(一旦它找到城市名称)

谁能给我一个解决方案,让我做我想做的事?(之后将其从doJob()更改为;)。谢谢大家!

编辑:这里我发布了我的最小版本的尝试。我希望这足够了

package net.maty;

public class Katastr extends Application {

final String programName = "KatastRED";

public static void main(String[] args) {
    launch(args);
}

@Override
public void start(Stage mainStage) throws Exception {
    try {
        mainStage.setTitle(programName);
        mainStage.setResizable(false);
        BorderPane root = (BorderPane)FXMLLoader.load(getClass().getResource("Katastr.fxml"));
        Scene scene = new Scene(root,800,500);
        scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());

        ChoiceBox threadNumberBox = (ChoiceBox) scene.lookup("#threadNumberBox");
        threadNumberBox.getSelectionModel().select(5);

        TextField linkField = (TextField) scene.lookup("#linkField");
        //debug
        linkField.setText("https://regiony.kurzy.cz/katastr/stary-kolin/objekty?strana=");
        //

        Text cityNameText = (Text) scene.lookup("#cityNameText");

        Button startButton = (Button) scene.lookup("#startButton");
        //HERE IS THE THING. EVERYTHING WORKS WELL EXCEPT THE FACT I CANT CHANGE CITYNAMETEXT
        startButton.setOnAction(e -> {
            String enteredUrl = linkField.getText();
            if(isValidUrl(enteredUrl)) {
                try {
                    cityNameText.setText("Example that will not show because it doesnt work.");
                    doJob(enteredUrl, cityNameText);
                } catch (IOException e1) {
                    e1.printStackTrace();
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }
            else {
                Alert alert = new Alert(AlertType.ERROR);
                alert.setTitle("Chyba!");
                alert.setHeaderText(null);
                alert.setContentText("Chybně zadané URL!");
                alert.showAndWait();
            }
        });
        mainStage.setScene(scene);
        mainStage.show();


    } catch(Exception e) {
        e.printStackTrace();
    }

}

public static void doJob(String validatedUrl, Text cityNameText) throws IOException, InterruptedException {
    Scanner in = new Scanner(System.in);
    String url = validatedUrl;      

    String cityName = getCityName(url);
    cityNameText.setText(cityName);

    List<String> parcelLinks = getParcelLinks(url);.....
}


public static List<String> getParcelLinks(String url) throws IOException{
}

public static List<String> getAdressesFromPage(Document doc) {
}


public static List<String> createParcelUrls(List<String> links) throws IOException {
}


public static boolean isValidUrl(String url) {
}

public static String getCityName(String url) throws IOException {
}




}
package net.maty;
公共类Katastr扩展了应用程序{
最终字符串programName=“katastered”;
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
public void start(阶段主体)引发异常{
试一试{
mainStage.setTitle(程序名);
mainStage.setresizeable(false);
BorderPane root=(BorderPane)FXMLLoader.load(getClass().getResource(“katasr.fxml”);
场景=新场景(根,800500);
scene.getStylesheets().add(getClass().getResource(“application.css”).toExternalForm());
ChoiceBox threadNumberBox=(ChoiceBox)场景。查找(“#threadNumberBox”);
threadNumberBox.getSelectionModel().select(5);
TextField linkField=(TextField)scene.lookup(“#linkField”);
//调试
linkField.setText(“https://regiony.kurzy.cz/katastr/stary-kolin/objekty?strana=");
//
Text cityNameText=(Text)scene.lookup(“#cityNameText”);
按钮开始按钮=(按钮)场景查找(“开始按钮”);
//事情是这样的。除了我不能改变CITYNAMETEXT之外,一切都很好
开始按钮。设置操作(e->{
字符串enteredUrl=linkField.getText();
如果(isValidUrl(enteredUrl)){
试一试{
setText(“由于不起作用而无法显示的示例”);
doJob(enteredUrl,cityNameText);
}捕获(IOE1异常){
e1.printStackTrace();
}捕捉(中断异常e1){
e1.printStackTrace();
}
}
否则{
Alert Alert=新警报(AlertType.ERROR);
警报。设置标题(“Chyba!”);
alert.setHeaderText(空);
setContentText(“ChybnězadanéURL!”);
alert.showAndWait();
}
});
主干。场景(场景);
show();
}捕获(例外e){
e、 printStackTrace();
}
}
公共静态void doJob(字符串validatedUrl,文本cityNameText)引发IOException、InterruptedException{
扫描仪输入=新扫描仪(系统输入);
字符串url=validatedUrl;
字符串cityName=getCityName(url);
cityNameText.setText(cityName);
List parcelLinks=getParcelLinks(url);。。。。。
}
公共静态列表getParcelLinks(字符串url)引发IOException{
}
公共静态列表GetAddresssFromPage(文档文档){
}
公共静态列表createParcelUrls(列表链接)引发IOException{
}
公共静态布尔值isValidUrl(字符串url){
}
公共静态字符串getCityName(字符串url)引发IOException{
}
}

发生了什么?代码是否编译?你有一个NullPointerException吗?您可能还希望创建并发布一个有效的日志,因为它实际上是有效的。它执行doJob()方法。现在发生的唯一一件事是不更改标签。事实上,如果要让应用程序保持响应性,就不能阻止JavaFX应用程序线程。您需要使用不同的线程,如果需要更新ui,请在新线程上使用
Platform.runLater
。或者,
任务
类提供了一些可以为您处理此问题的逻辑…您似乎试图将线性控制台程序与事件驱动GUI混合使用,但这永远不会起作用。您不需要后台线程,您只需要创建一个GUI,通过GUI获取输入,而不是通过控制台,而不是
系统。在
中。不要“一步一步”地执行此操作。这是您从头开始重新编写的机会,使用与OOP兼容的类和良好的结构,将UI与程序逻辑紧密分离。重新开始。