【问题标题】:Editing values/properties of an object of the controller class from another class从另一个类编辑控制器类对象的值/属性
【发布时间】:2018-02-05 19:48:05
【问题描述】:

我已尝试从此处遵循解决方案,但没有成功:JavaFX Change label text from another class with controller

我不确定他们是否想要和我一样。

所以基本上我拥有的是:FXMLDocumentController.javaFXMLDocument.xml, Operations.javaMain.java。 (我还有一些其他的类可以建立 Arduino 连接)

这是我在Main.java 中的启动方法:

@Override
public void start(Stage primaryStage) throws IOException {

    Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));

    Scene scene = new Scene(root);

    primaryStage.setTitle("This is the title");
    primaryStage.setScene(scene);
    primaryStage.show();

}

编辑: 这是我的 Operations.java:

public class Operations {

private String mensagem, hora, dados;
private String [] msgSeparada, dadosSeparados;
private int origem, destino, tipoMensagem, comprimento;
private int [] estadoDosSensores;

public FiltrarMensagem(String mensagem) {
    //remove o primeiro e ultimo carater
    mensagem = mensagem.substring(1, mensagem.length()-2);
    this.mensagem = mensagem;
    System.out.printf("Mensagem Recebida: %s\n", mensagem);
    msgSeparada = this.mensagem.split(";");
    destino = Integer.valueOf(msgSeparada[0]);
    origem = Integer.valueOf(msgSeparada[1]);
    hora = msgSeparada[2];
    tipoMensagem = Integer.valueOf(msgSeparada[3]);
    comprimento = Integer.valueOf(msgSeparada[4]);
    dados = msgSeparada[5];
    dadosSeparados = dados.split(",");
}

public void imprimir() {
    System.out.printf("Origem: %d\n", origem);
    System.out.printf("Destino: %d\n", destino);
    System.out.printf("Hora: %s\n", hora);
    System.out.printf("Tipo de Mensagem: %d\n", tipoMensagem);
    System.out.printf("Comprimento: %d\n", comprimento);
    System.out.printf("Dados: %s\n\n", dados);
    if(Integer.valueOf(dadosSeparados[0]) == 1) {
                //change label value here
    }

}

}

为简化起见,这是我的程序的作用:

我的控制器类有 2 个简单的按钮,这些按钮从 Arduino 的串行端口接收数据,并使用从 Arduino 接收的数据,我创建了操作类的对象,以便我可以根据需要进行必要的更改从 Arduino 接收到的数据,我想做的是更改标签和 FXML 文件中可用的所有对象,但我无法做到这一点。最简单的方法是什么?

我已经尝试了一切,但没有成功...如果有人可以帮助我,我将不胜感激。

【问题讨论】:

  • 您尚未向我们展示您尝试从 Operations 类更改控制器中的某些内容。没有看到就不可能知道你做错了什么,因此实际上不可能回答你的问题(你已经发布了一个可能的解决方案的链接 - 该解决方案有什么问题?)。
  • 我没有尝试该解决方案,因为我无法理解他们的问题,而且我认为这与我的不同。这就是为什么我要问我该怎么做......不过我已经添加了代码。
  • 也许我应该在之前的评论中更加小心。更新并没有太大帮助。实际上,我们需要更多信息和上下文,但可能没有那么多与问题无关的代码。是否可以制作一个显示问题的minimal reproducible example?你有一个带有标签的 FXML,它有一个控制器;然后你有另一个object,你想做一些导致标签更新的事情。我们不知道您在哪里实例化该对象,或者它是在哪里创建的,与 FXML 的加载位置有关。这就是您的示例代码需要展示的内容
  • 对不起,你是对的。是的,基本上我们可以假设我只有 4 个文件/类:主类,它基本上只加载 FXML 文件,FXML 文件本身,Controller 类和与这些类无关的其他类(操作) ,它只是从 arduino 接收消息并过滤数据,所以我可以在我的可视界面中显示它。这就是为什么我要更改此操作类的标签。
  • 可能您需要做的是创建一个模型类,并与您的控制器和其他将执行您操作的对象共享它的单个实例想要使标签更改其文本。您的模型可以有一个StringProperty,并且控制器可以将标签的文本绑定到它;那么您的其他对象可以更新该StringProperty。请参阅我对stackoverflow.com/questions/32342864/applying-mvc-with-javafx 的回答(它有多个控制器与单个模型实例交互,而不是控制器和另一个对象)。

标签: java javafx com


【解决方案1】:

简单案例的简单解决方案

如果您要实例化“其他类”以响应按钮按下,即在控制器中,您需要做的就是将新对象的引用传递给控制器​​。

public class Controller {

    @FXML
    private Label label ;

    public void showMessage(String message) {
        label.setText(message);
    }

    @FXML
    private void handleButtonPress(ActionEvent event) {
        Operations ops = new Operations(this);
        ops.doYourThing();
    }
}

然后

public class Operations {

    private final Controller controller ;

    public Operations(Controller controller) {
        this.controller = controller ;
    }

    public void doYourThing() {
        // ...

        String someMessage = ... ;
        controller.showMessage(someMessage);

        // ...
    }
}

MVC 方法

一个稍微更通用和健壮的解决方案是使用 MVC 方法,并创建一个模型类。您的模型类可以使用可观察的StringProperty 来保持要显示的文本。与控制器和服务类 (Operations) 共享模型实例。控制器可以观察属性,因此它可以在属性发生变化时更新标签,并且服务可以更新属性。这看起来像这样:

public class Model {

    private final StringProperty message = new SimpleStringProperty(); 

    public StringProperty messageProperty() P{
        return message ;
    }

    public final String getMessage() {
        return messageProperty().get();
    }

    public final void setMessage(String message) {
        messageProperty().set(message);
    }

}
public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
        Parent root = loader.load();
        Controller controller = loader.getController();

        Model model = new Model();
        controller.setModel(model);

        Scene scene = new Scene(root);

        primaryStage.setTitle("This is the title");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}
public class Controller {

    @FXML
    private Label label ;

    private Model model ;

    public void setModel(Model model) {
        this.model = model ;
        model.messageProperty().addListener((obs, oldMessage, newMessage) ->
            label.setText(newMessage));
    }

    @FXML
    private void handleButtonPress(ActionEvent event) {
        Operations ops = new Operations(model);
        ops.doYourThing();
    }
}

最后

public class Operations {

    private final Model model ;

    public Operations(Model model) {
        this.model = model ;
    }

    public void doYourThing() {
        // ...

        String someMessage = ... ;
        model.setMessage(message);

        // ...
    }
}

这种(稍微复杂一点)方法的好处是:

  1. 您移除了“服务”类与控制器之间的任何耦合,因此服务真正独立于 UI
  2. 如果服务是在其他地方创建的,这现在可以工作,因为您可以在更广泛的范围内访问模型(它是在 Main 类中创建的,这是应用程序的入口点)。

【讨论】:

  • 非常感谢!我终于用第一种方法成功了。我只需要找到一种方法从子类中“备份”数据,因为 Operations 类在其他类的 3 个实例下,但现在我知道如何建立连接!谢谢詹姆斯
  • 我正在使用此代码:“rxtx.qbang.org/wiki/index.php/Event_Based_Two_Way_Communication”与 Arduino 建立连接,在 SerialReader 类下我有操作类的实例化,你建议如何使这项工作保持介意我还有更多对象要编辑吗?
  • 所以我通过每个类作为参数传递了控制器,但现在我收到一个错误,因为使用的线程不是 javafx 线程(线程“线程 4”java.lang 中的异常。 IllegalStateException:不在 FX 应用程序线程上;currentThread = Thread-4)。这段代码使用一个线程来读取和一个线程来写入arduino,我正在从在线程上运行的SerialReader 类的“下方”过滤信息(使用Operations 类)。有什么解决办法吗? (我对 java 中的线程没有经验,或者根本没有线程)
  • @jks 这与您在此处发布的问题完全不同。幸运的是,这个论坛已经回答了很多次了 - 只需搜索错误消息即可。
  • @jks 此外,由于您的结构似乎相当复杂,因此通过将模型传递给多层依赖关系来手动“连接”所有内容可能会导致它过于复杂且无法维护。假设你有足够的 Java 经验来理解依赖注入框架,这些可以大大简化你的代码:见stackoverflow.com/questions/40539310/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-07
  • 2020-12-18
  • 2016-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多