JavaFX - Como criar janelas internas?

Uma ideia bem rápida: Seria com um JInternalFrame no JavaFX como eu poderia criar?

Estou usando FXML para fazer as telas ao clicar em uma opção no menu, estou criando telas mesmo, Stage. Mas não quero que seja uma tela independente, gostaria que fosse um JInternalFrame

Como eu poderia proceder?

Olá,
O JavaFx não possui internal frames, nesse caso você teria 3 opções para implementar essa funcionalidade no seu aplicativo:

Opção 1 - Utilizar o Swing embutido no JavaFX
Nesse caso você usaria o swingnode que é um componente do javaFX que permite que você adicione componentes swing dentro dele (como um JPanel). A idéia é a seguinte:

-> Crie a janela principal da sua aplicação e coloque um swingnode ao centro, como se fosse um JDesktopPane (e será).

-> Adicione um JDesktopPane nesse swingnode

-> Crie suas telas estendendo de JInternalFrame e como contentpane use um JFxPanel, isso lhe permitirá adicionar componenetes do JavaFX dentro do internal frame

-> Chame seu internalframe dentro do JDesktopPane

Criei uma gist com um exemplo aqui.

Opção 2 - utilizar bibliotecas de terceiros
Já existem bibliotecas que implementam essa função, posso citar duas:
Opção 1
Opção 2

Opção 3 - crie você mesmo
Essa opção apesar de ser a mais difícil é a que lhe permite maior controle e personalização, recentemente implementei uma internal frame para um sistema no qual trabalhei, não posso postar o fonte, mas posso mostrar o resultado:

As opções são essas, mas se tem experiência com swing e precisa fazer rápido sugiro a primeira opção, se tiver tempo e experiência com o fx sugiro a última opção. :grin:

2 curtidas

Segue possível solução:

Crie na sua janela principal um AnchorPane, onde poderá adicionar as janela internas, segue exemplo:

public class JavaFX_MDI extends Application {

@FXML
AnchorPane anchoPane;

@Override
public void start(Stage primaryStage) {
    Region root = null;
    try {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/javafx_mdi/FXML_Main.fxml"));
        fxmlLoader.setController(this);
        root = (Region) fxmlLoader.load();
    } catch (Exception ex) {
    }

    Scene scene = new Scene(root);

    Stage stage = new Stage();
    stage.setTitle("APP - Informações");
    stage.setScene(scene);
    stage.initModality(Modality.WINDOW_MODAL);
    stage.show();

}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    launch(args);
}

@FXML
private void handleJan1(ActionEvent event) throws IOException {
    System.out.println("Iniciando Janela Interna 1");
    try {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/javafx_mdi/FXML_Children01.fxml"));
        fxmlLoader.setController(this);
        Node n = (Node) fxmlLoader.load();
        anchoPane.getChildren().add(n);
    } catch (Exception ex) {
    }
}

@FXML
private void handleJan2(ActionEvent event) throws IOException {
    System.out.println("Iniciando Janela Interna 2");
    try {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/javafx_mdi/FXML_Children02.fxml"));
        fxmlLoader.setController(this);
        Node n = (Node) fxmlLoader.load();
        anchoPane.getChildren().add(n);
    } catch (Exception ex) {
    }
}

@FXML
private void handleJan3(ActionEvent event) throws IOException {
    System.out.println("Iniciando Janela Interna 3");
    try {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/javafx_mdi/FXML_Children03.fxml"));
        fxmlLoader.setController(this);
        Node n = (Node) fxmlLoader.load();
        anchoPane.getChildren().add(n);
    } catch (Exception ex) {
    }
}

}

1 curtida

Fiz diferente na minha aplicação. Resolvi trabalhar apenas com abas… Segue a imagem

Obrigado a todos que se preocuparam em responder. Levarei em consideração a resposta de vocês em um futuro próximo.

Ficou muito bom, com abas dá pra se trabalhar numa boa no fx, dá até para capturar o evento de fechar a aba (muito útil em alguns casos).

1 curtida