简体   繁体   中英

Can't redirect to an other FXML

Plop,

Me here because i need help, i'm totally lost, i've tried many times but still got this error.

Me trying to redirect the user on a login page to a signin page when he click on a button.

Me have error ():

Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: argument type mismatch
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
    at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275)
    at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
    at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1782)
    at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8865)
    at javafx.controls/javafx.scene.control.Button.fire(Button.java:200)
    at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:206)
    at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3876)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.access$1300(Scene.java:3604)
    at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1874)
    at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2613)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:397)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:434)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:395)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:433)
    at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
    at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:175)
    at java.base/java.lang.Thread.run(Thread.java:834)

Me try to redirect the user from (Login.fxml):

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Hyperlink?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.effect.Glow?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0" prefWidth="700.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="packages.home.Controller">
   <left>
      <AnchorPane prefHeight="500.0" prefWidth="346.0" style="-fx-background-color: #00a8cc;" BorderPane.alignment="CENTER">
         <children>
            <Text fill="#f5f5f5" layoutX="137.0" layoutY="218.0" strokeType="OUTSIDE" strokeWidth="0.0" text="MY FIT">
               <font>
                  <Font size="39.0" />
               </font>
            </Text>
            <Text fill="#f5f5f5" layoutX="44.0" layoutY="256.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Gérer vos séances sportives et plus encore" wrappingWidth="347.3798828125">
               <font>
                  <Font size="15.0" />
               </font>
            </Text>
            <Button fx:id="btnCreate" layoutX="140.0" layoutY="314.0" mnemonicParsing="false" onAction="#handleButtonAction" onMouseClicked="#handleButtonAction" prefHeight="33.0" prefWidth="111.0" style="-fx-background-color: #ffff;" text="Se connecter" textFill="#00a8cc">
               <effect>
                  <Glow />
               </effect></Button>
         </children>
      </AnchorPane>
   </left>
   <right>
      <AnchorPane prefHeight="500.0" prefWidth="356.0" BorderPane.alignment="CENTER">
         <children>
            <TextField fx:id="txtUsername" layoutX="84.0" layoutY="175.0" prefHeight="37.0" prefWidth="158.0" promptText="Nom d'utilisateur" />
            <PasswordField fx:id="txtPassword" layoutX="84.0" layoutY="239.0" prefHeight="39.0" prefWidth="158.0" promptText="Mot de passe" />
            <Button fx:id="btnConnect" layoutX="108.0" layoutY="313.0" mnemonicParsing="false" onMouseClicked="#handleButtonAction" prefHeight="33.0" prefWidth="111.0" style="-fx-background-color: #00a8cc;" text="Se connecter" textFill="WHITE">
               <effect>
                  <Glow />
               </effect></Button>
            <Hyperlink layoutX="48.0" layoutY="452.0" text="Vous avez oubliez votre mot de passe ?" />
            <Text fill="#00a8cc" layoutX="72.0" layoutY="121.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Authentification">
               <font>
                  <Font size="24.0" />
               </font>
            </Text>
            <Button fx:id="btnClose" layoutX="257.0" layoutY="-1.0" minWidth="49.0" mnemonicParsing="false" onMouseClicked="#handleButtonAction" prefHeight="30.0" prefWidth="60.0" style="-fx-background-color: #00a8cc;" text="Quitter" textFill="WHITE" />
            <Label fx:id="lblErrors" layoutX="87.0" layoutY="278.0" prefHeight="23.0" prefWidth="154.0" textFill="#dd1717" />
         </children>
      </AnchorPane>
   </right>
</BorderPane>

Main Controller (me redirecting the user in handleButtonAction - btnCreate) :

package packages.home;

import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.TextField;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import static javax.swing.JOptionPane.showMessageDialog;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class Controller extends Application {

    @FXML
    private Button btnClose;

    @FXML
    private TextField txtUsername;

    @FXML
    private TextField txtPassword;

    @FXML
    private Label lblErrors;

    @FXML
    private Button btnConnect;

    @FXML
    private Button btnCreate;

    /// --
    Connection laConnection = GestionConnection.getLaConnection();
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;


    public void handleButtonAction(MouseEvent event) throws IOException{

        if (event.getSource() == btnClose) {
            System.exit(0);
            System.out.println("Fermeture de l'application.");
        }

        if (event.getSource() == btnConnect) {

            //login here
            if (logIn().equals("Success")) {

                // On affiche une nouvelle scene
                try {
                    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("dashboard.fxml"));
                    Parent root1 = (Parent) fxmlLoader.load();
                    Stage stage = new Stage();
                    stage.initModality(Modality.APPLICATION_MODAL);
                    stage.initStyle(StageStyle.UNDECORATED);
                    stage.setTitle("MyFit - Mon Dashboard");
                    stage.setScene(new Scene(root1));
                    stage.show();
                } catch (Exception e){
                    System.out.println(e);

                }

                //add you loading or delays - ;-)
                Node node = (Node) event.getSource();
                Stage stage = (Stage) node.getScene().getWindow();

                //stage.setMaximized(true);
                stage.close();


            }
        }

        if (event.getSource() == btnCreate) {

            // On affiche une nouvelle scene
            try {
                FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Create.fxml"));
                Parent root1 = (Parent) fxmlLoader.load();
                Stage stage = new Stage();
                stage.initModality(Modality.APPLICATION_MODAL);
                stage.initStyle(StageStyle.UNDECORATED);
                stage.setTitle("MyFit - Inscription");
                stage.setScene(new Scene(root1));
                stage.show();
            } catch (Exception e){
                System.out.println(e);

            }

            //add you loading or delays - ;-)
            Node node = (Node) event.getSource();
            Stage stage = (Stage) node.getScene().getWindow();

            //stage.setMaximized(true);
            stage.close();




            }


    }



    private String logIn() {

        String status = "Success";
        String username = txtUsername.getText();
        String password = txtPassword.getText();

        if(username.isEmpty() || password.isEmpty()) {

            setLblErrors(Color.RED, "Champs vides.");
            status = "Error";

        } else {

            //query
            String sql = "SELECT * FROM admins Where username = ? and password = ?";

            try {

                // On test la requête
                System.out.println("Hello");
                preparedStatement = laConnection.prepareStatement(sql);
                preparedStatement.setString(1, username);
                preparedStatement.setString(2, password);
                resultSet = preparedStatement.executeQuery();

                if (!resultSet.next()) {
                    setLblErrors(Color.TOMATO, "Nom d'utilisateur ou mot de passe incorrect");
                    status = "Error";

                } else {
                    setLblErrors(Color.GREEN, "Authentification réussite, redirection en cours ...");
                    showMessageDialog(null, "Vous êtes bien connecté");

                }

            } catch (SQLException ex) {

                System.err.println(ex.getMessage());
                status = "Exception";
            }
        }
        return status;

    }


    private void setLblErrors(Color color, String text) {
        lblErrors.setTextFill(color);
        lblErrors.setText(text);
        System.out.println(text);
    }


    @Override
    public void start(Stage stage) throws Exception {

    }
}

Me try to print this fxml :'( :

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.DatePicker?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.effect.Glow?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>

<AnchorPane prefHeight="500.0" prefWidth="700.0" style="-fx-background-color: #00a8cc;" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="packages.home.CreateController">
   <children>
      <AnchorPane layoutX="234.0" layoutY="14.0" prefHeight="56.0" prefWidth="243.0" style="-fx-background-color: #ffff;">
         <children>
            <Text fill="#00a8cc" layoutX="66.0" layoutY="37.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Inscription">
               <font>
                  <Font size="24.0" />
               </font>
            </Text>
         </children>
      </AnchorPane>
      <AnchorPane layoutX="5.0" layoutY="393.0" prefHeight="107.0" prefWidth="700.0">
         <children>
            <CheckBox accessibleRoleDescription="ndr" layoutX="385.0" layoutY="45.0" mnemonicParsing="false" text="Confirmer l'inscription." textFill="WHITE" />
            <Button fx:id="btnCreate1" layoutX="216.0" layoutY="35.0" mnemonicParsing="false" prefHeight="32.0" prefWidth="134.0" style="-fx-background-color: #d63447;" text="Rejoindre MyFit" textFill="WHITE">
               <effect>
                  <Glow />
               </effect>
               <font>
                  <Font size="16.0" />
               </font>
            </Button>
         </children>
      </AnchorPane>
      <AnchorPane layoutX="154.0" layoutY="178.0" prefHeight="72.0" prefWidth="455.0">
         <children>
            <TextField layoutX="-29.0" layoutY="19.0" prefHeight="35.0" prefWidth="442.0" promptText="E-mail" />
         </children>
      </AnchorPane>
      <TextField layoutX="125.0" layoutY="134.0" prefHeight="35.0" prefWidth="167.0" promptText="Nom d'utilisateur" />
      <TextField layoutX="394.0" layoutY="134.0" prefHeight="35.0" prefWidth="173.0" promptText="Nom" />
      <TextField layoutX="393.0" layoutY="267.0" prefHeight="35.0" prefWidth="122.0" promptText="Pays" />
      <DatePicker layoutX="125.0" layoutY="267.0" prefHeight="35.0" prefWidth="147.0" promptText="Date de naissance" />
      <TextField layoutX="126.0" layoutY="346.0" prefHeight="35.0" prefWidth="173.0" promptText="Nom d'utilisateur " />
      <PasswordField layoutX="393.0" layoutY="346.0" prefHeight="35.0" prefWidth="173.0" promptText="Mot de passe" />
   </children>
</AnchorPane>

CreateController:

package packages.home;

import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

import java.net.URL;
import java.util.ResourceBundle;

public class CreateController implements Initializable {

private final AnchorPane rootPane;

    @FXML
    private TextField txtName;

    @FXML
    private TextField txtFirstname;

    @FXML
    private TextField txtEmail;

    @FXML
    private TextField txtCountry;

    @FXML
    private TextField txtUsername;

    @FXML
    private PasswordField txtPassword;

    @FXML
    private DatePicker datePicker;

    @FXML
    private CheckBox checkBox;

    @FXML
    private Button btnCreate1;

    public CreateController(AnchorPane rootPane) {
this.rootPane = rootPane
    }

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

    }
}

Me a student new to Java and JavaFX and i'm sure it have a lot of possibilies.

If you have any questions regarding this subject feel free to answer.

Me thanks in advance for your help, me really appreciate.

Inside your "Login.fxml" FXML file, you have this button:

<Button fx:id="btnCreate" layoutX="140.0" layoutY="314.0" mnemonicParsing="false" 
        onAction="#handleButtonAction" onMouseClicked="#handleButtonAction" 
        prefHeight="33.0" prefWidth="111.0" 
        style="-fx-background-color: #ffff;" text="Se connecter" textFill="#00a8cc">

Notice you defined both onAction and onMouseClicked to invoke the same method. Yet in Controller you have:

public void handleButtonAction(MouseEvent event) throws IOException {
    // method body omitted for brevity
}

This won't work. The onAction expects an ActionEvent and the onMouseClicked expects a MouseEvent . You need to either:

  1. Bad: Change the parameter type to a supertype of both ActionEvent and MouseEvent (eg Event ).
  2. Good: Remove either onAction or onMouseClicked from the button element in the FXML. Preferably you'd remove the latter as the onAction handler is the proper way to do something when a button is interacted with.

    If you keep onAction then you need to change from MouseEvent to ActionEvent .

Option two is by far the best option. Keeping both handlers will cause the method to be invoked twice.


You will also have a problem with your CreateController . When you define a controller with fx:controller , and don't use a custom controller factory, the FXMLLoader attempts to reflectively create the controller via the no-arg constructor. Since CreateController does not have a no-arg constructor this will cause an exception to be thrown (specifically a NoSuchMethodException , I believe).

There are at least three possible solutions:

  1. Remove fx:controller from the FXML file and manually set the controller instance:

     FXMLLoader loader = new FXMLLoader(); loader.setController(new CreateController(/* AnchorPane instance */)); // invoke #load() **after** setting the controller
  2. Keep the fx:controller in the FXML and set a custom controller factory:

     FXMLLoader loader = new FXMLLoader(); loader.setControllerFactory(clazz -> { if (clazz == CreateController.class) { return new CreateController(/* AnchorPane instance */); } throw new UnsupportedOperationException(); }); // invoke #load() **after** setting the controller factory
  3. Keep the fx:controller , use a no-arg constructor in CreateController , and add a way to pass the AnchorPane after the fact:

     FXMLLoader loader = new FXMLLoader(); // configure loader... loader.load(); // must invoke #load() **before** getting the controller instance loader.<CreateController>getController().setAnchorPane(/* AnchorPane insatnce */);

    In this case, it's best to just get rid of the constructor in CreateController since it no longer does anything. If no constructor is declared then an implicit no-arg "default constructor" is added by the compiler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM