JavaFX 2.0 FXML дочерние окна

После долгих поисков я нашел этот вопрос Как создать приложение javafx 2.0 МДИ. Что я действительно хотел знать, так это то, могу ли я создать всплывающее окно или дочернее окно в главном окне, используя компоненты JavaFX и Scene Builder для создания нового окна.

Я закончил с этим для модального всплывающего окна:

В классе Main я хотел сохранить первичную стадию в поле, к которому я могу получить доступ из моего основного класса контроллера. Итак, я добавил к нему статическую переменную Stage, а это в методе Main.Start():

primaryController.primaryStage = primaryStage;

Это метод, который использует кнопка в основном контроллере:

public void OnBtnShowChild(ActionEvent event) {
    MessageBoxController msgBox = new MessageBoxController();
    try {
        msgBox.showMessageBox(primaryStage);
    } catch (Exception e) {
        e.printStackTrace(); 
    }
}

Это класс MessageBoxController, который я создал с помощью Scene Builder. Он имеет базовую компоновку стандартного всплывающего окна, которое можно использовать для отображения значка (ImageView), текстового поля (для текста вашего сообщения) и двух кнопок (для функций ДА/НЕТ). Я еще не уверен, как передать результаты того, какая кнопка была нажата обратно в основной контроллер.

public class MessageBoxController implements Initializable {

@FXML
// fx:id="btnNo"
private Button btnNo; // Value injected by FXMLLoader

@FXML
// fx:id="btnYes"
private Button btnYes; // Value injected by FXMLLoader

@FXML
// fx:id="imgMessage"
private ImageView imgMessage; // Value injected by FXMLLoader

@FXML
// fx:id="txtMessage"
private TextField txtMessage; // Value injected by FXMLLoader

private Stage myParent;
private Stage messageBoxStage;

public void showMessageBox(Stage parentStage) {
    this.myParent = parentStage;

    try {
        messageBoxStage = new Stage();
        AnchorPane page = (AnchorPane) FXMLLoader.load(MessageBoxController.class.getResource("/MessageBox/MessageBoxFXML.fxml"));
        Scene scene = new Scene(page);
        messageBoxStage.setScene(scene);
        messageBoxStage.setTitle("Message Box");
        messageBoxStage.initOwner(this.myParent);
        messageBoxStage.initModality(Modality.WINDOW_MODAL);
        messageBoxStage.show();
    } catch (Exception ex) {
        System.out.println("Exception foundeth in showMessageBox");
        ex.printStackTrace();
    }
}
@Override
public void initialize(URL fxmlFileLocation, ResourceBundle arg1) {
    txtMessage.setText("Howdy");

}

public void OnBtnYes(ActionEvent event) {

}

public void OnBtnNo(ActionEvent event) {

}

}

И, наконец, это файл FXML, который я создал в Scene Builder:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.net.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane id="AnchorPane2" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"   
      prefHeight="172.0" prefWidth="524.0" xmlns:fx="http://javafx.com/fxml" fx:controller="MessageBox.MessageBoxController">
  <children>
    <VBox prefHeight="172.0" prefWidth="524.0" styleClass="vboxes" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
      <children>
        <HBox alignment="CENTER" prefHeight="109.99990000000253" prefWidth="516.0" spacing="30.0">
          <children>
            <ImageView fx:id="imgMessage" fitHeight="110.0" fitWidth="146.66666666666666" pickOnBounds="true" preserveRatio="true" styleClass="null" />
            <TextField fx:id="txtMessage" editable="false" prefHeight="47.0" prefWidth="325.0" />
          </children>
          <stylesheets>
        <URL value="@MyCSS.css" />
      </stylesheets>
    </HBox>
    <HBox alignment="CENTER" prefHeight="58.0" prefWidth="516.0" spacing="30.0">
      <children>
        <Button fx:id="btnYes" mnemonicParsing="false" onAction="#OnBtnYes" text="Button" />
        <Button fx:id="btnNo" mnemonicParsing="false" onAction="#OnBtnNo" text="Button" />
      </children>
    </HBox>
  </children>
  <stylesheets>
    <URL value="@MyCSS.css" />
  </stylesheets>
</VBox>
</children>
<stylesheets>
<URL value="@MyCSS.css" />
</stylesheets>
</AnchorPane>

С помощью этого я могу создать модальное всплывающее окно, а также хочу создать другие дочерние окна для отображения данных другими способами с использованием различных элементов управления. И, самое главное, я могу использовать Scene Builder для создания макета.

Что вы думаете? Это хороший способ сделать это, пока они не добавят реальную поддержку в Java 8 и JavaFX 8?


person Rick Falck    schedule 03.05.2013    source источник
comment
Ваше решение в порядке. Возьмите все после того, как я закончил с этим, вырежьте это из вопроса и добавьте его как самостоятельный ответ и отметьте ответ как правильный.   -  person jewelsea    schedule 03.05.2013
comment
Я понимаю. Я новичок в Java и только что изучил JavaFX, взяв доступные учебные пособия и выполнив поиск в Google. Информации, кроме основ, просто нет. Таким образом, я понятия не имею, является ли то, что я опубликовал, хорошим способом решения проблемы или нет, даже если это работает. Почему никто другой не подумал бы об этом, если это хорошее решение? Все, что я нашел, было другими очень запутанными вещами, которые не использовали JavaFX.   -  person Rick Falck    schedule 03.05.2013
comment
Большинство решений для окон сообщений JavaFX представляют собой просто код Java, а не использование FXML для макета. Я подал запрос документации RT-27567 Создать официальное руководство по созданию общих диалоговых окон приложений< /а>.   -  person jewelsea    schedule 03.05.2013
comment
На самом деле, вышеуказанное решение НЕ работает. Проблема в том, что статический метод FXMLLoader строит корневой элемент управления из файла FXML и создает новый экземпляр класса контроллера в рамках своей обработки, и нет никакого способа получить его. Я просто отделил класс контроллера от его создания. Теперь это работает как модальный диалог, и вы можете получить результат того, какая кнопка была нажата.   -  person Rick Falck    schedule 03.05.2013
comment
Я заставил его работать, но, как вы сказали ранее, было бы не задавать вопрос, чтобы опубликовать мое решение. Я бы просто сделал это, чтобы поделиться тем, что я сделал. Я выбрал этот сайт, потому что он часто появляется в результатах поиска Google, и я не мог найти для него лучшего места. Что бы вы предложили мне сделать с ним? Спасибо.   -  person Rick Falck    schedule 03.05.2013
comment
Учтите, что вы можете получить контроллер из FXMLLoader, если вы создать экземпляр и загрузить его с помощью нестатического load(), он, вероятно, вам не поможет, и, вероятно, вам все равно нужно выполнить создание экземпляра контроллера извне из кода контроллера.   -  person jewelsea    schedule 03.05.2013
comment
Также обратите внимание на showAndWait() Shows this stage and waits for it to be hidden (closed) before returning to the caller для этапа окна сообщения, а не show(), если вы хотите, чтобы запрос отображал диалоговое окно и получал от него результат, который отображался синхронно с вызывающим кодом.   -  person jewelsea    schedule 03.05.2013


Ответы (1)


вы пробовали с групповым классом? вы можете добавлять различные элементы с помощью fxml и контроллеров.

Group root= new Group(); 
AnchorPane frame=FXMLLoader.load(getClass().getResource("frame.fxml"));
AnchorPane  content=  FXMLLoader.load(getClass().getResource("principal.fxml"));
root.getChildren().add(window);
root.getChildren().add(frame);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
person Csharls    schedule 01.10.2013