Switch between fxml files

╄→гoц情女王★ 提交于 2019-12-20 07:28:53

问题


I have created an application using jfxPanel inside swing component. The problem I am facing is I am not being able to change the fxml files. When a button of the fxml is clicked, I want to dispose that fxml and load another fxml file there. This is what I have done till now

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;
}   

}

The BottomPanelIncommingController class. The fxml controller

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();
    }
 }

回答1:


You should never instantiate the controller with new when you are using FXML because the job to instantiate the controller is done by the FXMLLoader. While instantiating the controller, it also creates instances of the nodes which are there in the FXML and inject them into the controller.

If you do not get the controller instance from the FMXLLoader, all your nodes inside the controller which are annotated with @FXML eill be null. Therefore, you must always get the Controller out of the fxml.

In your case, you should use

bpic = fxmlLoader.getController();

instead of

bpic = new BottomPanelIncomingController();

Update

To change the FXML on click of a button

Let us consider the following method is called on Button click

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

You can load the FXML and set it on a Scene and then to the 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);
} 

Note : I am not sure what you are trying to achieve here, consider this as an example just to load FXML on click of a button and apply your logic.



来源:https://stackoverflow.com/questions/25883532/switch-between-fxml-files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!