2016-11-25 1536 views
1

我有一个简化的例子,其中fx:id的代码引用在调用initialize时不为空,但在函数调用后立即变为null。什么是获得这种参考的正确方法?这是sample.fxml如何通过javafx中的fx:id获取对节点的引用?

<GridPane alignment="center" hgap="10" vgap="10" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="sample.Main"> 
    <columnConstraints> 
     <ColumnConstraints /> 
    </columnConstraints> 
    <rowConstraints> 
     <RowConstraints /> 
    </rowConstraints> 
    <children> 
     <Text fx:id="textRef" strokeType="OUTSIDE" strokeWidth="0.0" text="Hello world" /> 
    </children> 
</GridPane> 

这是被宣布为它的控制器Main.java

public class Main extends Application implements Initializable{ 
    @FXML 
    public Text textRef; 

    @Override 
    public void start(Stage primaryStage) throws Exception{ 
     Parent root = FXMLLoader.load(getClass().getResource("sample.fxml")); 
     primaryStage.setTitle("Hello World"); 
     primaryStage.setScene(new Scene(root, 300, 275)); 
     primaryStage.show(); 

     this.someNewFunction(); 
    } 

    private void someNewFunction() { 
     this.textRef.setText("Changed in somNewFunction"); 
    } 


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

    @Override 
    public void initialize(URL location, ResourceBundle resources) { 
     this.textRef.setText("Changed at initialize"); 
    } 
} 

文本裁判是initialize调用内部有效,但抛出时someNewFunction内一个NullPointerException。

+0

不要使用'Application'子类作为控制器。为控制器定义一个新类。 –

回答

3

时启动是一个不同的对象比由FXMLLoader创建的Main实例被用作控制器的Main实例。

恕我直言,这将是更好装载FXML后能得到从FXMLLoader控制器,还可以使用不同类的Application作为控制器:

public class MainController implements Initializable { 

    ... 

} 
<GridPane alignment="center" hgap="10" vgap="10" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="sample.MainController"> 
    ... 
</GridPane> 
@Override 
public void start(Stage primaryStage) throws Exception { 
    FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml")); 
    Parent root = loader.load(); 
    primaryStage.setTitle("Hello World"); 
    primaryStage.setScene(new Scene(root, 300, 275)); 
    primaryStage.show(); 

    MainController controller = loader.getController(); 

    controller.someNewFunction(); 
} 

但是,您也可以指定应与fxml一起使用的控制器:

<GridPane alignment="center" hgap="10" vgap="10" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8"> 
    ... 
</GridPane> 
@Override 
public void start(Stage primaryStage) throws Exception { 
    FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml")); 
    loader.setController(this); 
    Parent root = loader.load(); 
    primaryStage.setTitle("Hello World"); 
    primaryStage.setScene(new Scene(root, 300, 275)); 
    primaryStage.show(); 

    this.someNewFunction(); 
} 
-1

您正在执行javafx循环外部的someNewFunction。 我的意思是,show方法结束后,主线程接受控制,并且javafx组件不再存在(它们被销毁,因为它们不再需要它们)。 您必须将someNewFunction绑定到附加到某些FXML元素引用的某个事件(即通过SceneBuilder上的setOnAction或通过代码实现的Button),将方法调用放在initialize方法内,或者只需在primaryStage.show ()线。

希望这有助于

+0

处理javafx以外的事件的javafx方法是什么?例如,如果我必须下载解析'someNewFunction'内的json文件, – Subra

+1

这个答案中没有任何语句是真实的。 –

相关问题