JavaFX: Switching between two panes

生来就可爱ヽ(ⅴ<●) 提交于 2020-06-13 09:12:11

问题


I'm developing a "random enemy generator" for a friends D&D board and since I'm practing Java I wanted to try out. I want it to have 2 anchor panels:

  1. In the first one you give value to the following attributes of the object Foes:

    • Nombre (name)
    • HP
    • Energia(Energy)
    • Mana

Once done, you save those selections and the enemies get included in the generator.

  1. You generate the random enemy, with his values and scalating according to your character level.

My question is, how I can get from the first to the second? I have pretty clear how to develop both individually but not how to mix them.

I just have the code for the second one because, initially I didn't think about customizing it. I don't think any of the code regarding this screen is relevant but if u want it just tell me!

edit: I tried by my own and I managed everything to create 2 fxml files and set the controllers but I'm getting the following error when I push my button to switch between panels:

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774)
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Node.fireEvent(Node.java:8411)
    at javafx.scene.control.Button.fire(Button.java:185)
    at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
    at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$345(GlassViewEventHandler.java:432)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
    at com.sun.glass.ui.View.notifyMouse(View.java:937)
    at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication.lambda$null$203(GtkApplication.java:139)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
    ... 48 more
Caused by: java.lang.NullPointerException: Location is required.
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3207)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
    at com.croma.generadordd.FXMLcontroller.loadSecond(FXMLcontroller.java:34)
    ... 58 more

This is my code:

FXMLcontroller.java

public class FXMLcontroller implements Initializable { 
    @FXML
    AnchorPane rootPanel;
    Button pase;

    @Override
    public void initialize(URL url, ResourceBundle rb) {        
    }

    @FXML
    private void loadSecond (ActionEvent event) throws IOException{
        AnchorPane pane = FXMLLoader.load(getClass().getClassLoader().getResource("Scene.fxml"));
        rootPanel.getChildren().setAll(pane);
    }    
}    

MainApp.java

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class MainApp extends Application {
  public MainApp() {     
  }

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("/fxml/SelectScreen.fxml"));

        Scene scene = new Scene(root);
       scene.getStylesheets().add("/styles/Styles.css");

        stage.setTitle("JavaFX and Maven");
        stage.setScene(scene);
        stage.show();       
    }

    /**
     * The main() method is ignored in correctly deployed JavaFX application.
     * main() serves only as fallback in case the application can not be
     * launched through deployment artifacts, e.g., in IDEs with limited FX
     * support. NetBeans ignores main().
     *
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);  
    }
}

secondScreen.java

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import java.util.Random;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.TextArea;
import javafx.scene.layout.AnchorPane;

public class secondScreen implements Initializable {
    Random aleat = new Random();
    int monstruo = aleat.nextInt(10);
    int numeroEnemigos = aleat.nextInt(4) + 1;
    //1.         //6.
    //2.         //7.
    //3.        //8.
    //4.        //9.
    //5.        //10.

    @FXML
    private void handleButtonAction(ActionEvent event) {
    Random aleat = new Random();
    final int monstruo = aleat.nextInt(10);
    int numeroEnemigos = aleat.nextInt(4) + 1;
    Foes enemigo0 = new Foes("Enemigo0", 0, 0, 0);

    switch(monstruo){
        case 0: resultado.setText("Aparece(n)" + "\t" + numeroEnemigos + "\t" + 
                "\t"+ enemigo0.Nombre+ ",\t" + "\t" +"preparate a luchar!");
        break;

        case 1: resultado.setText("Aparece(n)" + "\t" + numeroEnemigos + "\t" + 
                "monstruo(s)2, preparate a luchar!");
        break;
        case 2: resultado.setText("Aparece(n)" + "\t" + numeroEnemigos + "\t" +
                "monstruo(s)3, preparate a luchar!");
        break;
        case 3: resultado.setText("Aparece(n)" + "\t" + numeroEnemigos + "\t" +
                "monstruo(s)4, preparate a luchar!");
        break;
        case 4: resultado.setText("Aparece(n)" + "\t" + numeroEnemigos + "\t" +
                "monstruo(s)5, preparate a luchar!");
        break;
        case 5: resultado.setText("Aparece(n)" + "\t" + numeroEnemigos + "\t" +
                "monstruo(s)6, preparate a luchar!");
        break;
        case 6: resultado.setText("Aparece(n)" + "\t" + numeroEnemigos + "\t" +
                "monstruo(s)7, preparate a luchar!");
        break;
        case 7: resultado.setText("Aparece(n)" + "\t" + numeroEnemigos + "\t" +
                "monstruo(s)8, preparate a luchar!");
        break;
        case 8: resultado.setText("Aparece(n)" + "\t" + numeroEnemigos + "\t" +
                "monstruo(s)9, preparate a luchar!");
        break;
        case 9: resultado.setText("Aparece(n)" + "\t" + numeroEnemigos + "\t" +
                "monstruo(s)10, preparate a luchar!");
        break;
    }

    //RELLENAR CON DATOS DE ENEMIGOS
    switch(monstruo){
        case 0: inste.setText(String.valueOf("Nombre:" +" "+enemigo0.Nombre+"\n"+"Vida:"+
    " "+enemigo0.Hp+"\n"+"Energía:"+" "+enemigo0.E+"\n"+"Maná:"+" "+enemigo0.M));
        break;
    }
    //"Las stats del enemigo son (Hp/energía/maná"+
           //   "\t" + 
    }

    @FXML
    Label resultado;

    @FXML
    Label inste;

    @Override
    public void initialize(URL url, ResourceBundle rb) {

    }
}    

Scene.FXML controller by secondScreen.java

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

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

<AnchorPane id="AnchorPane" prefHeight="469.0" prefWidth="484.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.croma.generadordd.secondScreen">
    <children>
        <Button fx:id="button" layoutX="14.0" layoutY="392.0" onAction="#handleButtonAction" prefHeight="38.0" prefWidth="301.0" text="Genera un enemigo" />
      <Label fx:id="resultado" layoutX="11.0" layoutY="344.0" prefHeight="38.0" prefWidth="462.0" />
      <ImageView fitHeight="379.0" fitWidth="469.0" layoutX="8.0" layoutY="8.0" pickOnBounds="true" preserveRatio="true">
         <image>
            <Image url="@Dungeons-and-Dragons-characters.jpg" />
         </image>
      </ImageView>
      <TextField layoutX="405.0" layoutY="399.0" prefHeight="0.0" prefWidth="24.0" />
      <Text layoutX="373.0" layoutY="416.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Nv." />
      <Label fx:id="inste" layoutX="7.0" layoutY="275.0" prefHeight="62.0" prefWidth="469.0" />
    </children>
</AnchorPane>

SelectScreen.FXML controlled by FXMLcontroller.java

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

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

<AnchorPane id="AnchorPane" fx:id="rootPanel" prefHeight="469.0" prefWidth="484.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.croma.generadordd.FXMLcontroller">
   <children>
      <TextField layoutX="14.0" layoutY="69.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="14.0" layoutY="106.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="133.0" layoutY="69.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="133.0" layoutY="106.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="251.0" layoutY="106.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="251.0" layoutY="69.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="370.0" layoutY="69.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="370.0" layoutY="106.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="14.0" layoutY="146.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="133.0" layoutY="146.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="251.0" layoutY="146.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="370.0" layoutY="146.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="133.0" layoutY="187.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="14.0" layoutY="187.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="251.0" layoutY="187.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="370.0" layoutY="187.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="14.0" layoutY="228.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="133.0" layoutY="228.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="251.0" layoutY="228.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="370.0" layoutY="228.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="14.0" layoutY="268.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="133.0" layoutY="268.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="251.0" layoutY="268.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="370.0" layoutY="268.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="14.0" layoutY="308.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="133.0" layoutY="308.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="251.0" layoutY="308.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="370.0" layoutY="308.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="14.0" layoutY="344.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="133.0" layoutY="344.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="251.0" layoutY="344.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="370.0" layoutY="344.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="14.0" layoutY="381.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="133.0" layoutY="381.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="251.0" layoutY="381.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="369.0" layoutY="381.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="14.0" layoutY="419.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="133.0" layoutY="419.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="251.0" layoutY="419.0" prefHeight="25.0" prefWidth="101.0" />
      <TextField layoutX="369.0" layoutY="419.0" prefHeight="25.0" prefWidth="101.0" />
      <Label layoutX="-2.0" prefHeight="41.0" prefWidth="336.0" text=" D&amp;D GENERATOR 1.0" textAlignment="CENTER">
         <font>
            <Font size="30.0" />
         </font>
      </Label>
      <Label layoutX="383.0" layoutY="448.0" prefHeight="15.0" prefWidth="88.0" text="Coded by CRoma">
         <font>
            <Font size="10.0" />
         </font>
      </Label>
      <Label layoutX="9.0" layoutY="44.0" text="Nombre enemigo" />
      <Label layoutX="175.0" layoutY="44.0" text="HP" />
      <Label layoutX="277.0" layoutY="44.0" text="Energía" />
      <Label layoutX="403.0" layoutY="44.0" text="Maná" />
      <Button fx:id="pase" layoutX="363.0" layoutY="5.0" mnemonicParsing="false" onAction="#loadSecond" prefHeight="34.0" prefWidth="113.0" text="JUEGA!" />
   </children>
</AnchorPane>


回答1:


The following code demonstrates how to switch between two panes.
It is also mcve which you can use as a reference for future questions(1).

import java.io.IOException;                                                                                         
import javafx.application.Application;                                                                              
import javafx.fxml.FXMLLoader;                                                                                      
import javafx.scene.Scene;                                                                                          
import javafx.scene.control.Button;                                                                                 
import javafx.scene.layout.BorderPane;                                                                              
import javafx.scene.layout.Pane;                                                                                    
import javafx.scene.layout.StackPane;                                                                               
import javafx.stage.Stage;                                                                                          

public class SwitchPanesDemo extends Application                                                                    
{                                                                                                                   

    private Pane page0, page1;                                                                                      
    private Button toggle;                                                                                          
    String[] buttonText = {"Show Page 1", "Show Page 2"};                                                           

    @Override                                                                                                       
    public void start(Stage primaryStage) {                                                                         
        try {                                                                                                       

            page0 = (Pane) FXMLLoader.load(getClass().getResource("redPane.fxml"));                                 
            page1 = (Pane) FXMLLoader.load(getClass().getResource("yellowPane.fxml"));                              
            page0.visibleProperty().bind(page1.visibleProperty().not());//make sure only one pane is visible        
            page1.setVisible(false);                                                                                
            StackPane stackPane = new StackPane(page0, page1);//add both panes to a stack pane                      
            BorderPane root = new BorderPane(stackPane);                                                            
            toggle = new Button(buttonText[0]);                                                                     
            toggle.setOnAction(e->togglePages(toggle.getText()));                                                   
            root.setBottom(toggle);                                                                                 
            Scene scene = new Scene(root);                                                                          
            primaryStage.setScene(scene);                                                                           
            primaryStage.show();                                                                                    
        }                                                                                                           
        catch (IOException e) {                                                                                     
            e.printStackTrace();                                                                                    
        }                                                                                                           
    }                                                                                                               

    private void togglePages(String text) {                                                                         

        if(buttonText[0].equals(text)){                                                                             
            page1.setVisible(true);                                                                                 
            toggle.setText(buttonText[1]);                                                                          
        }else{                                                                                                      
            page1.setVisible(false);                                                                                
            toggle.setText(buttonText[0]);                                                                          
        }                                                                                                           
    }                                                                                                               

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

redPane.fxml

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

<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" 
prefHeight="200.0" prefWidth="300.0" style="-fx-background-color: red;" 
xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Label layoutX="87.0" layoutY="87.0" text="Red AnchorePane" textAlignment="CENTER" textFill="#faf907">
         <font>
            <Font size="16.0" />
         </font>
      </Label>
   </children>
</AnchorPane>

yellowPane.fxml

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

<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>   

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" 
prefHeight="200.0" prefWidth="300.0" style="-fx-background-color: yellow;" 
xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Label layoutX="87.0" layoutY="87.0" text="Yellow AnchorePane" textAlignment="CENTER" textFill="#fa1b07">
         <font>
            <Font size="16.0" />
         </font>
      </Label>
   </children>
</AnchorPane>


(1) SO policy is:
"Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself..."

来源:https://stackoverflow.com/questions/56926885/javafx-switching-between-two-panes

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