JavaFX - 标签 - 如何访问类成员

时间:2012-09-17 23:36:42

标签: label javafx-2 fxml

所以我的问题非常简单。当他们是String而不是Label时,我可以在单独的类中访问类成员,但是当他们 时,我似乎无法访问 em> Label。使用JDK 7u6(w / JavaFX 2.2)。

简单的例子。第一个工作,第二个工作不工作。可以在第一个示例中分配foo.label,但我在第二个示例中获得了NullPointer。任何人都可以在下面的第二个例子中解释为什么foo.label为空?

更新:我从原始问题中删除了@FXML注释,因为我认为它们不是我所遇到的问题所必需的。另外,请参阅我对answer by @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>

2 个答案:

答案 0 :(得分:3)

在你的第二个例子中,你永远不会将foo标签初始化为任何东西,因此它将保持为空。

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

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

1。摆脱Foo

  • @FXML public Label label;移至SampleController
  • 删除Foo类并确保您的fxml定义fx:id="label"

2。初始化SampleController中的Foo标签

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

3。使Foo成为嵌套控制器

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

第三种方式似乎与您想要的最接近,文档的文档位于FXML文档简介的Nested Controllers部分。

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

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

答案 1 :(得分:1)

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

首先,在例1中:

public String label;

是String而不是Label。而且我很确定你没有在FXML文件中使用String(不是你不能,但它不会在舞台上显示)

无论如何,当你使用“=”符号时,你正在初始化你的字符串,当你把 @FXML 放在一个没有实现Initializable接口的类中时,你没有从你的FXML初始化任何东西file(顺便说一句,必须引用Initializable作为它的控制器),因此,你引用了一个null对象。

要修复示例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>

我希望它有所帮助。欢呼声。