Java 为什么可以';我不能在按钮事件下使用setText()?
所以我将我的复杂控制台程序重新设计成GUI。然而,我是一个非常没有经验的JavaFX用户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();
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与程序逻辑紧密分离。重新开始。