2

所以我的问题很简单。当他们是 a而不是 a时,我可以访问单独班级中的班级成员,但当他们时,我似乎不能。使用 JDK 7u6(带 JavaFX 2.2)。StringLabel Label

简单的例子。第一个有效,第二个无效。 foo.label可以在第一个示例中分配,但我在第二个示例中得到一个 NullPointer。谁能解释为什么foo.label在下面的第二个示例中为 null ?

更新:我从原始问题中删除了@FXML 注释,因为我认为它们对于我遇到的问题不是必需的。另外,请参阅@jewelsea对答案的评论......最后,为了完整性,我添加了我的 FXML 文件(在 Q 的底部)。

这有效:

// Example 1:
public class SampleController implements Initializable {
    Foo foo = new Foo();

    public void handleButtonAction(ActionEvent event) {
        System.out.println("You clicked me!");
        foo.label = "Hello World!";
        System.out.println(foo.label);
    }

    @Override public void initialize(URL url, ResourceBundle rb) {
    }    
}

// Example 1 -- Foo.java:
public class Foo {
    public String label;
}

不起作用

// Example 2:
public class SampleController implements Initializable {
    Foo foo = new Foo();

    public void handleButtonAction(ActionEvent event) {
        System.out.println("You clicked me!");
        foo.label.setText("Hello World!");  // gives NullPointer exception !!
    }

    @Override public void initialize(URL url, ResourceBundle rb) {
    }    
}

// Example 2 -- Foo.java:
import javafx.scene.control.Label;

public class Foo {
    public Label label;
}

这是我的 FXML 文件,用于上述任一示例:

<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxapplication4.SampleController">
    <children>
        <Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
        <Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" text="hey!" />
    </children>
</AnchorPane>
4

2 回答 2

3

在您的第二个示例中,您永远不会将 foo 标签初始化为任何内容,因此它将保持为空。

您确实创建了一个 Foo 对象,Foo foo = new Foo();但这不会初始化 Foo 内部的标签字段成员。特别是,@FXML 注释不会以您在提供的代码中使用它的方式做任何事情。这是因为 Foo 不是控制器。

允许您的示例运行的一些方法:

1. 摆脱 Foo

  • 搬进@FXML public Label label;你的SampleController.
  • 摆脱Foo类并确保您的 fxml 定义了fx:id="label".

2. 在 SampleController 中初始化 Foo 标签

  • 将以下代码放入示例控制器的初始化方法中:foo.label = new Label();.
  • 此外,在初始化时,将 foo 标签添加到某个容器(例如布局窗格)中,以便它可见。

3. 使 Foo 成为嵌套控制器

  • 保留 Foo 类。
  • @FXML Foo foo;使用而不是初始化控制器中的 Foo 实例Foo foo = new Foo();
  • 使 Foo 类成为控制器(实现Initializable或定义具有适当签名的初始化方法)。
  • 在您引用的 fxml 中SampleController,还有fx:include一个新的 foo.xml 文档的声明,该文档将fx:id="label"Foo 实例设置为允许初始化。

第三种方式似乎与您想要的最接近,并且它的文档位于 FXML 文档简介的嵌套控制器部分。

注意:这个问题更多的是关于如何使用@FXML 初始化类的成员,然后是如何访问类成员。访问只是通过普通的 getter/setter 或成员字段访问,就像您在示例中已经拥有的那样。

foo.label = "Hello World!";您的第一个示例有效,因为您在使用之前明确地将 foo.label 初始化为新字符串(使用)。

于 2012-09-18T00:45:25.773 回答
1

伙计,你把整个事情搞混了!但它发生了。

首先,在示例 1 中:

public String label;

是字符串而不是标签。而且我很确定您没有在 FXML 文件中使用字符串(不是说您不能,但它根本不会显示在舞台中)

无论如何,当您使用“=”符号时,您正在初始化您的字符串,当您将@FXML放在不实现 Initializable 接口的类中时,您不会从 FXML 文件中初始化任何内容(顺便说一下,必须引用可初始化,因为它是控制器),因此,您正在引用一个空对象。

要解决示例 2 中的问题,您需要:

// 示例 2:

import javafx.fxml.FXML;
import javafx.scene.control.Label;

public class SampleController implements Initializable {
    @FXML public Label label;

    @FXML private void handleButtonAction(ActionEvent event) {
        System.out.println("You clicked me!");
        foo.label.setText("Hello World!");  // gives NullPointer exception !!
    }

    @Override public void initialize(URL url, ResourceBundle rb) {
    }    
}

并确保您有一个 FXML 文件,例如:

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

<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.control.Button?>

<AnchorPane xmlns:fx="http://javafx.com/fxml" fx:id="whatever-id" fx:controller="samplecontroller.package.SampleController">
   <children>
      <Label fx:id="label" text="not really necessary" />
      <Button fx:id"btnLabelChanger" onmouseclick="#handleButtonAction"/>
   </children>
</AnchorPane>

我希望它有所帮助。干杯。

于 2012-09-18T00:55:22.327 回答