2015-02-24 3 views
0

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

В Swing это было легко, но я не могу найти синтаксис для него в JavaFx? Итак, в этом случае, с моим примером кода, как мне это сделать?

public class Main extends Application { 

    Parent root; 
    Scene scene; 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml")); 

     scene = new Scene(root); 

     primaryStage.setScene(scene); 

     primaryStage.sizeToScene(); 
     primaryStage.setResizable(false); 

     primaryStage.show(); 


     root.setOnMouseClicked((MouseEvent mouseEvent) -> { 
      if (mouseEvent.getButton().equals(MouseButton.PRIMARY)) { 
       if (mouseEvent.getClickCount() == 2) { 



         Stage stage = new Stage(); 
         stage.setScene(primaryStage.getScene()); 
         stage.show(); 
         primaryStage.close(); 


       } 
      } 
     }); 
    } 


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

Попытка создать новое окно: http://sv.tinypic.com/r/1jkq4w/8

FXML:

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

<?import java.lang.*?> 
<?import java.util.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 
<?import java.lang.*?> 
<?import java.util.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 
<?import javafx.scene.paint.*?> 
<?import javafx.scene.text.*?> 

<VBox prefHeight="430.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="blackjack.FXMLDocumentController"> 
    <children> 
    <AnchorPane maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS"> 
     <children> 
      <Label fx:id="labelPlayerTotal" layoutX="510.0" layoutY="335.0" prefHeight="15.0" prefWidth="121.0" text="Playertotal:" /> 
      <Label fx:id="labelDealerTotal" layoutX="510.0" layoutY="359.0" prefHeight="15.0" prefWidth="112.0" text="Dealertotal:" /> 
      <TextArea fx:id="dealerArea" layoutY="29.0" prefHeight="159.0" prefWidth="503.0" /> 
      <TextArea fx:id="playerArea" layoutY="244.0" prefHeight="159.0" prefWidth="503.0" /> 
      <Button fx:id="stayButton" layoutX="512.0" layoutY="173.0" mnemonicParsing="false" onAction="#drawCardForDealer" prefHeight="25.0" prefWidth="72.0" text="STAY" /> 
      <Button fx:id="hitButton" layoutX="512.0" layoutY="130.0" mnemonicParsing="false" onAction="#drawCardForPlayer" prefHeight="25.0" prefWidth="72.0" text="HIT" /> 
      <Label fx:id="labelWinner" layoutX="104.0" layoutY="208.0" prefHeight="15.0" prefWidth="296.0" /> 
      <MenuBar fx:id="helpBar"> 
       <menus> 
       <Menu mnemonicParsing="false" text="Help"> 
        <items> 
        <MenuItem mnemonicParsing="false" onAction="#aboutApplication" text="About" /> 
        </items> 
       </Menu> 
       </menus> 
      </MenuBar> 
     </children> 
    </AnchorPane> 
    </children> 
</VBox> 
+0

Нужно ли вам расположить окно или просто распоряжаться текущей FXML работает и для вас? – ItachiUchiha

+0

* «.. всякий раз, когда эта кнопка нажата, я хочу, чтобы текущее окно было удалено, и новый, который будет показан. В Swing это было легко, ..» * Легко, может быть, но не рекомендуется. См. [Использование нескольких JFrames, хорошая/плохая практика?] (Http://stackoverflow.com/q/9554636/418556). Если Java-FX ограничивает разработчика одним «фреймом», который должен быть чем-то в своем жалуют. –

+0

@AndrewThompson Спасибо, Андрей, мне нужна эта кнопка перезагрузки в моем приложении JavaFX, это очень необходимо для моего приложения. Это возможно? –

ответ

0

Вы можете просто скрыть (то есть отчуждать) окно, вызвав hide() или close() на него. И вы можете просто показать новое окно с точно таким же кодом, который вы использовали раньше:

   primaryStage.close(); 

       Stage stage = new Stage(); 

       root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml")); 

scene = new Scene(root); 

stage.setScene(scene); 

stage.sizeToScene(); 
stage.setResizable(false); 

stage.show(); 

Но это кажется слишком много для того, что вы хотите достичь. Почему бы просто не заменить корень существующей сцены и использовать существующий этап?

try { 
    scene.setRoot(FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"))); 
} catch (Exception exc) { 
    exc.printStackTrace(); 
    throw new RuntimeException(exc); 
} 

Обратите внимание, что (как вы это делаете) теперь вы заменили корень сцены; новый корень не имеет того же обработчика мыши, связанного с ним. Если вы используете второй метод, вы можете просто поместить обработчик на сцену (который не меняется). Или, может быть, лучше, что вы можете определить слушателя в FXML и контроллер:

<VBox prefHeight="430.0" prefWidth="640.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="blackjack.FXMLDocumentController" 
fx:id="root" 
onMouseClicked="reload"> 
<!-- ... --> 
</VBox> 

и контроллер:

package blackjack ; 

public class FXMLDocumentController { 

    // ... 

    @FXML 
    private VBox root ; 

    // ... 

    @FXML 
    private void reload() throws Exception { 

     // Really, it would be way better here to reset the whole UI to its initial 
     // state, instead of reloading it from scratch. This should work as a 
     // quick hack though. 
     Scene scene = root.getScene(); 
     scene.setRoot(FXMLLoader.load(Main.class.getResource("FXMLDocument.fmxl"))); 
    } 

    // ... 
} 
+0

Он работал хорошо. Когда я дважды щелкаю, текущее окно расположено и отображается новый. Большой! Но когда я снова пробую это в новом окне, функция не работает. Вы знаете, почему он работал только в первый раз? Разве нельзя просто убить все с помощью System.exit и загрузить новый интерфейс? –

+0

О, да, потому что слушатель мыши добавляется только к первому корню, который затем заменяется. Я обновлю. –

+0

Да, я согласен с тем, что сброс всего пользовательского интерфейса лучше. Это очень грязно, но, в любом случае, спасибо. Если бы я сбросил весь пользовательский интерфейс, не хватило бы System.exit и затем загрузить fxml? Или как я могу это сделать? –

Смежные вопросы