JavaFX Unexpected NullPointerException [重复]

Posted

技术标签:

【中文标题】JavaFX Unexpected NullPointerException [重复]【英文标题】:JavaFX Unexpected NullPointerException [duplicate] 【发布时间】:2022-01-05 21:08:23 【问题描述】:

我正在开发一个使用 JavaFX 和 MVC 架构的游戏项目

这是我的观点之一

package fr.arnoux23u.javano.mvc.views;

import fr.arnoux23u.javano.mvc.*;
import javafx.fxml.*;
import javafx.scene.control.TextArea;

import java.net.URL;
import java.util.ResourceBundle;

/**
 * @author arnoux23u
 */
public class ServerView implements Initializable, Observer 

    @FXML
    private TextArea clientsList;

    @Override
    public synchronized void update(Model m) 
        System.out.println("[UPDATE] "+Thread.currentThread().getName());
        clientsList.setText("test");
    

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) 
        System.out.println("[INITIALIZE] "+Thread.currentThread().getName());
        clientsList.setText("Aucun joueur ici");
    

还有我的 FXML 文件

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>

<VBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fr.arnoux23u.javano.mvc.views.ServerView">
    <Label text="JavaNo - Server">
        <font>
          <Font size="23.0" />
        </font>
    </Label>
    <Label alignment="CENTER" text="Connected Clients">
        <font>
          <Font size="23.0" />
        </font>
    </Label>
    <TextArea fx:id="clientsList" editable="false" maxWidth="200.0" prefHeight="200.0" prefWidth="200.0" style="-fx-focus-color: -fx-control-inner-background;" text="&#10;&#10;">
      <VBox.margin>
         <Insets top="20.0" />
      </VBox.margin>
      <font>
         <Font size="18.0" />
      </font></TextArea>
</VBox>

当我加载应用程序时,TextArea clientsList 的文本正确设置为“Aucun jueur ici”,但是当我想更新文本(使用 MVC)时,我有一个 @987654325 @ 在 clientsList

首先,我认为这是一个线程错误,因为运行update 方法的线程不是“JavaFX 应用程序线程”

所以在我的 MVC 控制器中,我使用 Platform.runlater() 方法。

@Override
    public void notifyObservers() 
        observers.forEach(o -> 
            System.out.println("[FOREACH] "+Thread.currentThread().getName());
            Platform.runLater(() -> 
                System.out.println("[PLATFORM] "+Thread.currentThread().getName());
                o.update(this);
            );
        );
    

我调用更新时的输出是

[INITIALIZE] JavaFX Application Thread
[FOREACH] Thread-3
[PLATFORM] JavaFX Application Thread
[UPDATE] JavaFX Application Thread

但即使使用 runLater 方法,我也有 NullPointerException

这是完整的堆栈跟踪

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException: Cannot invoke "javafx.scene.control.TextArea.setText(String)" because "this.clientsList" is null
    at fr.arnoux23u.javano/fr.arnoux23u.javano.mvc.views.ServerView.update(ServerView.java:34)
    at fr.arnoux23u.javano/fr.arnoux23u.javano.mvc.Game.lambda$notifyObservers$1(Game.java:54)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
    at java.base/java.lang.Thread.run(Thread.java:833)

我希望有人可以帮助我。

谢谢

【问题讨论】:

您的错误在代码中,您没有提供。你是如何注册你的观察者实例的?它们是什么?它们不是由 fxml 加载器创建的实例。如果您需要帮助,您可能需要编辑问题以提供minimal reproducible example。 关于上述(是),但您最有可能在做Game#addObserver(new ServerVIew()) 或类似的事情,而不是实际使用在应用程序中创建的ServerView(99.9% 的问题是控制器没有通过@FXML 处理)。 “不,相同的实例哈哈” -> 这是什么意思?您创建的实例和 fxml 加载器创建的实例怎么可能相同?您是否将 fxml 加载程序中的控制器设置为您在 one part of this answer 中创建的实例。我不这么认为。而且您的代码还显示您没有从加载程序中获取控制器,这是执行此操作的另一种方式。 你真的只是嘲笑我的评论,然后发布你的代码,表明你正在做你所嘲笑的事情。 ServerView sv = new ServerView(); 这不会通过 FXML 调用,也不会创建 clientsList。我不知道该说什么。 当你写“lol”时,它意味着大声笑出来。因此,当您写“不,相同的情况,哈哈”时,您是在忽略向您提供的建议并对此大笑,就好像他们提出了荒谬的建议一样。 “是时候停止看不起人了。”您也可以遵循此建议,而不是嘲笑您不理解或不觉得有帮助的建议。 【参考方案1】:

请参阅description of FXMLoader operation 的第 3 步:

如果根元素上有 fx:controller 属性,FXMLLoader 会创建指定类的实例。

因此,如果您在代码中显式创建了一个新实例,并且加载器也创建了一个新实例,那么只有加载器实例才会注入 fxml 值。

我很确定,这就是你的代码正在发生的事情。

【讨论】:

以上是关于JavaFX Unexpected NullPointerException [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Android开发中java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx}: java.lang.NullPoi

Unexpected end of input 和 Unexpected token var 和 Unexpected token ;

Import Unexpected identifier + SyntaxError: Unexpected string

python IndentationError: unexpected indent

“set_unexpected”在 VC2010 中不起作用?

com.fasterxml.jackson.core.JsonParseException: Unexpected character