【问题标题】:How can I reference the same FXML element from an instance of the same class如何从同一类的实例中引用相同的 FXML 元素
【发布时间】:2016-09-17 15:54:01
【问题描述】:

对不起,我是 JavaFX 的新手。 我的设置: 我有一个始终显示的主要 FXML GUI。在这个主 GUI 中,我在 AnchorPane 中加载了另一个 FXML。

第二个 FXML 最初使用以下方法加载到此 AnchorPane(位于主 GUI 中):

@FXML
private AnchorPane rootSetPane;

然后我从那里使用rootSetPane。 这是位于同一主 GUI fxml 中的 AnchorPane。

<AnchorPane fx:id="rootSetPane" layoutX="228.0" prefHeight="710.0" prefWidth="887.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="228.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />

初始化主控制器(主GUI一直显示)

@Override
public void initialize(URL url, ResourceBundle rb) {
    AnchorPane paneHome;
    try {
        paneHome = FXMLLoader.load(getClass().getResource("HomePage.fxml"));
        rootSetPane.getChildren().setAll(paneHome);          
    } catch (IOException ex) {
        Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
    }
}

此主类中的工作方法示例(从同一主 FXML 中的按钮调用):

@FXML
private void foodFinder(ActionEvent event) throws IOException {      
    AnchorPane paneFoodFinder = FXMLLoader.load(getClass().getResource("ScreenFoodFinder.fxml"));

    rootSetPane.getChildren().setAll(paneFoodFinder);    
}

一个不起作用的方法示例(使用对象调用):

public void setPanel() throws IOException {
   AnchorPane newPane = FXMLLoader.load(getClass().getResource("NewPane.fxml"));
rootSetPane.getChildren().setAll(newPane);  
}

我在程序期间使用主 GUI 中的按钮多次设置了第二个窗格(这有效)。尝试从主控制器类外部设置此窗格时会出现问题。我不能使用 Main 类的实例并调用方法来访问 rootSetPane(我不能使 rootSetPane 静态)。我收到了NullPointerException。我确信这是一个业余错误。有没有办法可以使用上述方法更改此rootSetPane

或者我必须创建其他类来管理我的屏幕。最简单(甚至肮脏)​​的解决方案将不胜感激。
如果我能够在主 GUI 中触发按钮,它也会起作用,但这会导致相同的问题 (NullPointerException)。我有一种感觉,我不能使用类的对象来引用元素,我也不能使这些元素成为静态的。

【问题讨论】:

    标签: java javafx fxmlloader


    【解决方案1】:

    您可以创建一个扩展 AnchorPane 的类。该类将成为 fxml 的控制器。因此您可以创建它的实例:

     SpecialAnchorClass anchor = new SpecialAnchorClass();
    

    提到在 SceneBuilder 中您必须检查:

    所以你的 SpecialAnchorClass 会是这样的:

    public class SpecialAnchorClass extends AnchorPane implements Initializable{
    
        //..@fxml nodes
    
        /**
         * Constructor
         */
       public SpecialAnchorClass(){
             //FXMLLOADER
            FXMLLoader loader = new FXMLLoader(getClass().getResource("..path to fxml file"));
            loader.setController(this);
            loader.setRoot(this);
    
            try {
                loader.load();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
       @Override
         public void initialize(URL location, ResourceBundle resources) {
    
    
               //when this method is called every fxml component has been initialized
         }
    
    }
    

    【讨论】:

    • 什么时候在我的程序序列中创建这个类的对象?
    • @lolftw 您可以将其创建为 Main 类的成员,或者您可以随时创建它并将其设为静态 final。
    • 正如我所提到的,我对此完全陌生,我认为我执行此错误。我收到此错误:javafx.fxml.LoadException: Root hasn't been set. Use method setRoot() before load.
    • @lolftw 是的,这就是添加图像的原因。您必须检查[使用 fx:root 构造]。您是如何制作 fxml 的?
    【解决方案2】:

    检查getClass().getResource("NewPane.fxml") 是否指向正确的文件。

    【讨论】:

    • 文件名正确。但是“rootSetPane”会出现错误(与上述相同的错误)。此行不起作用:'rootSetPane.getChildren()'。
    • 如何初始化rootSetPane
    • 我认为这个问题的答案是否定的。我已经使用主 gui 控制器的对象从另一个类调用方法。如何以另一种方式调用此方法(或正确调用?)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-25
    • 1970-01-01
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多