在Simulaton程序中更改其他对象时如何更新SceneBuilder GUI?

我正在用Java编程模拟器应用程序。有3个不同的类别。这些类中的某些更改必须更改GUI中的TextField(由SceneBuilder创建)。在gui中单击按钮,必须更改类中的对象。我使用SceneBuilder制作了GUI,我知道如何使用Controller类。 有什么方法可以对对象类中的FXML使用控制器类来填充TextField中的文本?像这样:

@Override
public void run() {
    while (0 != 1) {
        if (!stack.isEmpty())
            controls.settfAI("INFECTED"); //controls is FXML controller // settfAI is id of text field
        try {
            sleep(3000);
        } catch (InterruptedException e) {
            CCLogger.cclogger(Watchman.class.getName(),Level.INFO,e);
        }   
    }
}

第二个问题,当我单击按钮时,可以编写控件类中对象的更改吗?像这样:

@FXML
Button btnOne; //btnOne is id in SceneBuilder file
//...
// AmbulanceCar ambulanceCar=new AmbulanceCar();
public void clicked() {
    ambulanceCar.go(); // send ambulance car in some location 
}

我的程序有很多按钮和3个TextField,必须更改模拟器的状态。

更新: 我有城市和搬家的人。当人被感染时,Watchman必须在TextField中看到人的位置。我有带按钮和文本字段的fxml。我知道Watchman类必须具有fxml的Controler。我得到了控制者

        Parent watchBtns = FXMLLoader.load(getclass().getResource("ControlGUI.fxml"));
    URL contronLinkUrl=Paths.get("/ControlGUI.fxml").toUri().toURL();
    FXMLLoader loader=FXMLLoader.load(contronLinkUrl);

然后,我将Controler发送给Watchman类,

city.getWatchman().setControler(loader.getcontroller());

在Watchman类中,我尝试使用以下代码编辑TextField:

    public void setControler(ControlerControlGUI controlGUI)
{
    controlerControlGUI=controlGUI;
    System.out.println("Controler set!");
}

@Override
public void run()
{
    System.out.println("Watchman started!");
    while(0!=1)
    {
        try {
        if(!stack.isEmpty())
            { 
              controlerControlGUI.settfAI("INFECTED");
            }

            sleep(3000);
        } catch (InterruptedException e) {
            CCLogger.cclogger(Watchman.class.getName(),e);
        }   
    }
}

现在我出错了

由以下原因引起:java.lang.ClassCastException:类javafx.scene.layout.AnchorPane无法转换为类javafx.fxml.FXMLLoader(javafx.scene.layout.AnchorPane位于加载程序“ app”的模块javafx.graphics中; javafx.fxml.FXMLLoader在加载程序'app'的模块javafx.fxml中

更新,如果下面的回答对您来说很复杂... 在控制器类中,您可以放置​​要控制的对象。就我而言,是这样的:

Person infectedPerson;
Ambulance ambulance;

//call in main function
public void setInfectedInfo(Person person,Ambulance amb)
{
    infectedPerson=person;
    ambulance=amb;
}

在另一个类中,我将这段代码用于为fxml和class设置相同的控制器,这两个控制器都将使用它们

Stack<Alarm> stack= new Stack<>();
Vector<Ambulance> ambulances=new Vector<>();
ControlerControlGUI controlerControlGUI;

public void setControler(ControlerControlGUI controlGUI)
{
    controlerControlGUI=controlGUI;
}

在主类中,您可以放置​​:

    FXMLLoader loader=new 
       FXMLLoader(getclass().getResource("ControlGUI.fxml"));
    Parent watchBtns=loader.load();
    city.getWatchman().setControler(loader.getcontroller());
    watchBtns.setLayoutX(840);
    watchBtns.setLayoutY(100);
    groupCity.getchildren().add(watchBtns);

我将尝试解释最后的代码部分。首先,使用已定义控制器的fxml文件制作FXMLLoader。然后,您加载它。 (如果您不调用load(),将无法使用)。之后,您必须调用getcontroller才能在函数中具有相同的控制器,并且可以从外部调用控制器功能来控制GUI部分。

iCMS 回答:在Simulaton程序中更改其他对象时如何更新SceneBuilder GUI?

在这里,您可以将Object的文本绑定到LabelTextField上,以通过操纵对象和相反的方式来操纵GUI。

请注意,此答案侧重于您的问题,但没有为您提供复制粘贴解决方案。为此,我将整个项目(包括pom.xml)推送到了repo on my GitHub上,以防您想要克隆它并玩转。

我在Maven中使用了模块化项目,您可以找到各种方法来设置环境here

应用程序:(主类)

package com.broudy;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

/**
 * JavaFX App
 */
public class App extends Application {

    private static Scene scene;

    @Override
    public void start(Stage stage) throws IOException {
        scene = new Scene(loadFXML("primary"));
        stage.setScene(scene);
        stage.show();
    }

    static void setRoot(String fxml) throws IOException {
        scene.setRoot(loadFXML(fxml));
    }

    private static Parent loadFXML(String fxml) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource(fxml + ".fxml"));
        return fxmlLoader.load();
    }

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

}

值班人员:

package com.broudy;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Watchman {

  private StringProperty manipulatedText;

  public Watchman() {
    this.manipulatedText = new SimpleStringProperty("howdy!");
  }

  public String getManipulatedText() {
    return manipulatedText.get();
  }

  public StringProperty manipulatedTextProperty() {
    return manipulatedText;
  }

  public void setManipulatedText(String manipulatedText) {
    this.manipulatedText.set(manipulatedText);
  }
  
}

PrimaryController:

package com.broudy;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;

public class PrimaryController {

  @FXML
  private Label manipulatedLBL;

  @FXML
  private Button primaryButton;

  @FXML
  private TextField manipulatedTF;

  @FXML
  private Button manipulateWatchmanBTN;

  private int i = 0;

  @FXML
  private void initialize() {
    List<String> texts = new ArrayList<>();
    texts.add("Hey! It works... Click again...");
    texts.add("Again...");
    texts.add("And again...");
    texts.add("Wohooo");
    texts.add("Yipeeeeeee!");
    texts.add("Notice: ...");
    texts.add("The text is changed in Watchman class but these change as well...");

    Watchman watchman = new Watchman();
    manipulatedTF.textProperty().bind(watchman.manipulatedTextProperty());
    manipulatedLBL.textProperty().bind(watchman.manipulatedTextProperty());

    //    This is another acceptable way of assigning actions to buttons,etc.
    manipulateWatchmanBTN.setOnAction(click -> {
      watchman.setManipulatedText(texts.get(i++));
      // This is just to reset the text
      if (i >= texts.size()) {
        i = 0;
      }
    });
  }
  
  @FXML
  private void switchToSecondary() throws IOException {
    App.setRoot("secondary");
  }
}

简要说明:

PrimaryController创建Watchman的实例,并将其textPropertymanipulatedText)绑定到TextFieldLabeltextProperty

请注意,这里的绑定是单向的,这意味着只有manipulatedText影响TextFieldLabel,而不是相反。为此,您可以使用bindBidirectional

现在,单击manipulateWatchmanBTN仅更改Watchman的{​​{1}}的文本-这是您第二个问题的答案。因为我们将GUI绑定到它,所以使用SceneBuilder创建的GUI元素也会更改-这是您第一个问题的答案

可以根据您的特定需求进行调整。

本文链接:https://www.f2er.com/1950701.html

大家都在问