【问题标题】:Switch between fxml files在 fxml 文件之间切换
【发布时间】:2014-09-17 06:16:19
【问题描述】:

我在 swing 组件中使用 jfxPanel 创建了一个应用程序。我面临的问题是我无法更改 fxml 文件。单击 fxml 的按钮时,我想处理该 fxml 并在那里加载另一个 fxml 文件。 这是我到目前为止所做的事情

public class NonResponsiveButtons extends JFrame {
    NonResponsiveButtons nrb;
    BottomPanelIncomingController bpic;
    JPanel panel; 
    JPanel bPanel;

    private int applicationWidth_600 = 600;
    private int applicationHeight_600 = 600;

    private int upperPanelHeight_535 = 535;
    private int bottomPanelHeight_65 = (applicationHeight_600-upperPanelHeight_535); 


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



    public NonResponsiveButtons(){
        final JFXPanel fxPanel = new JFXPanel();

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
            // TODO Auto-generated method stub
                try{
                    new JFXPanel();
                    add(getJPanel(), BorderLayout.CENTER);
                    add(getJBottomPanel(), BorderLayout.PAGE_END);
                    bPanel.add(fxPanel, BorderLayout.CENTER);

                    Platform.runLater((new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        initFX(fxPanel);    
                    }
                })) ;

            }
                catch(Exception e){
                    System.out.println("Error in swing utilities thread :" + e.getMessage());
            }

        }
    });

    this.setSize(applicationWidth_600, applicationHeight_600);
    setLocationRelativeTo(null);
    BorderLayout borderLayout = new BorderLayout();
    setLayout(borderLayout);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     
    setVisible(true);
}


private void initFX(JFXPanel jfxPanel) {
    try {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("fxmlDesign.fxml"));
        Parent root = (Parent) fxmlLoader.load();
        Scene scene = new Scene(root, 600, 65);
        jfxPanel.setScene(scene);

        fxmlLoader.getController();
        bpic = new BottomPanelIncomingController();
        bpic.setNonResoinsiveButtons(this);

    } catch (IOException exc) {
        exc.printStackTrace();
        System.exit(1);
    }
}

public void loadSecondFxml(){
    System.out.println("loading second fxml");
}   

private JPanel getJPanel(){
    if(panel == null){
    panel = new JPanel();
    panel.setSize(applicationWidth_600,upperPanelHeight_535);
    panel.setBackground(Color.gray);
    }
    return panel;
}

private JPanel getJBottomPanel(){
    if(bPanel == null){
        bPanel = new JPanel();
        bPanel.setSize(applicationWidth_600, bottomPanelHeight_65);
        bPanel.setBackground(new Color(8, 16, 19));
    }
    return bPanel;
}   

}

BottomPanelIncommingController 类。 fxml 控制器

public class BottomPanelIncomingController implements Initializable {
 NonResponsiveButtons nrb;

    @Override
    public void initialize(URL arg0, ResourceBundle arg1) {
    // TODO Auto-generated method stub
    System.out.println("HEllo");
    }

    public void setNonResoinsiveButtons(NonResponsiveButtons nrb){
    this.nrb = nrb;
    }

    @FXML
    public void callAccepted(ActionEvent event){
    System.out.println("From controller");
    nrb.loadSecondFxml();
    }
 }

【问题讨论】:

  • 有什么问题?您是否收到任何错误/异常?
  • 空指针异常。当我在 BottomPanelIncomingController 类中的setNonResoinsiveButtons(NonResponsiveButtons nrb) 中。我已经编辑了我的问题并在我的问题中添加了 BottomPanelIncomingController 代码
  • 您必须始终将控制器从 fxml 中取出。使用bpic = fxmlLoader.getController(); 而不是bpic = new BottomPanelIncomingController();
  • 感谢您的成功。现在我想在单击 fxml 文件的按钮时重新调整 fxml 文件。我该怎么做

标签: java swing javafx fxml fxmlloader


【解决方案1】:

当您使用 FXML 时,切勿使用 new 实例化控制器,因为实例化控制器的工作是由 FXMLLoader 完成的。在实例化控制器的同时,它还会创建 FXML 中存在的节点实例并将它们注入到控制器中。

如果您没有从 FMXLLoader 获取控制器实例,则控制器内所有带有 @FXML 注释的节点都将为空。因此,您必须始终将 Controller 从 fxml 中取出。

在你的情况下,你应该使用

bpic = fxmlLoader.getController();

而不是

bpic = new BottomPanelIncomingController();

更新

点击按钮更改 FXML

让我们考虑在按钮点击时调用以下方法

@FXML
public void callAccepted(ActionEvent event){
    System.out.println("From controller");
    nrb.loadSecondFxml();
}

您可以加载 FXML 并将其设置在场景中,然后设置到 JFXPanel

public void loadSecondFxml(){
    //Load new FXML and assign it to scene
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("newFXML.fxml"));
    Parent root = (Parent) fxmlLoader.load();
    Scene scene = new Scene(root, 600, 65);
    jfxPanel.setScene(scene);
} 

注意:我不确定您要在这里实现什么,将其视为一个示例,只是为了在单击按钮时加载 FXML 并应用您的逻辑。

【讨论】:

  • 谢谢你成功了。我假设首先我必须删除 jfxpanel 的当前组件,然后在那里加载另一个 fxml 文件,但这样做是可行的。最后一个问题,之前的 fxml 文件对象是否仍然存在或已被处置?因为我们没有手动处理它
猜你喜欢
  • 2021-10-03
  • 2018-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-04
相关资源
最近更新 更多