You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fxweaver加载FXML文件失败,提示未指定控制器问题求助

登录页面加载失败:FXML未指定控制器异常

加载登录页面时反复触发以下异常:

「Caused by: net.rgielen.fxweaver.core.FxLoadException: Unable to load FXML file file:/C:/Users/vinic/smrf/target/classes/br/edu/ifnmg/smrf/Apresentacao/Desktop/login.fxml」
「Caused by: javafx.fxml.LoadException: No controller specified./C:/Users/vinic/smrf/target/classes/br/edu/ifnmg/smrf/Apresentacao/Desktop/login.fxml:52」

已检查pom.xml、重启VSCode、核对文件路径均无问题,刚引入FontAwesomeIcons库。

控制器代码

package br.edu.ifnmg.smrf.Apresentacao.Desktop;

import javafx.fxml.Initializable;
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import br.edu.ifnmg.smrf.servicos.AutenticacaoServico;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXMLLoader;
import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.AnchorPane;
import net.rgielen.fxweaver.core.FxmlView;

@Service
@FxmlView("login.fxml")
public class LoginController extends Controller {

    @Autowired
    private AutenticacaoServico autenticacao;

    // @Autowired
    // private LogServico logs;

    @FXML
    private Button close;

    @FXML
    private TextField inpLoginEmail;

    @FXML
    private PasswordField inpLoginSenha;

    @FXML
    private Button loginBtn;

    @FXML
    private AnchorPane viewLogin;

    public LoginController() {

    }

    @FXML
    public void autenticar(Event e) {
        String login = inpLoginEmail.getText();
        String senha = inpLoginSenha.getText();

        if (autenticacao.autenticar(login, senha)) {
            //carregarScene(painelNovoUsuario, NovoUsuarioController.class);

            // Alert alert = new Alert(AlertType.INFORMATION, "deu certo", ButtonType.OK);
            // alert.showAndWait();

            // logs.registrar(LogNivel.Informacao, "Login", txtLogin.getText());

            // carregarScene(viewLogin, TelaPrincipalController.class);

            // alert.showAndWait();
        } else {
            // logs.registrar(LogNivel.Erro, "Login", txtLogin.getText());
            // Alert alert = new Alert(AlertType.CONFIRMATION, "Erro ao acessar o sistema.
            // Deseja sair?", ButtonType.NO, ButtonType.NO);
            // alert.showAndWait();

            Alert alert = new Alert(
                AlertType.WARNING,
                "Não foi possível acessar o sistema. Verifique se os dados informados estão corretos.",
                ButtonType.OK)
            ;
            alert.showAndWait();
        }
    }

    @FXML
    public void irParaNovoUsuario(Event e) {
        //carregarScene(painelNovoUsuario, NovoUsuarioController.class);
    }
}

FXML文件代码

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

<?import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.PasswordField?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.text.Font?>

<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/20.0.1" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <AnchorPane prefHeight="200.0" prefWidth="200.0">
         <children>
            <AnchorPane layoutX="5.0" layoutY="2.0" prefHeight="400.0" prefWidth="306.0" styleClass="left-form" stylesheets="@lib/web/loginDesign.css">
               <children>
                  <ImageView fitHeight="400.0" fitWidth="324.0" layoutX="-24.0" layoutY="14.0" pickOnBounds="true" preserveRatio="true">
                     <image>
                        <Image url="@images/SMRF.png" />
                     </image>
                  </ImageView>
               </children>
            </AnchorPane>
            <AnchorPane fx:id="viewLogin" layoutX="312.0" layoutY="3.0" prefHeight="400.0" prefWidth="300.0" styleClass="right-form" stylesheets="@lib/web/loginDesign.css">
               <children>
                  <Label layoutX="81.0" layoutY="57.0" stylesheets="@lib/web/loginDesign.css" text="Bem Vindo!" textFill="#256b51">
                     <font>
                        <Font name="Tahoma Bold" size="24.0" />
                     </font>
                  </Label>
                  <TextField fx:id="inpLoginEmail" layoutX="40.0" layoutY="153.0" prefHeight="30.0" prefWidth="220.0" promptText="Matrícula" styleClass="textfield" stylesheets="@lib/web/loginDesign.css" />
                  <Label layoutX="48.0" layoutY="126.0" text="Login:" textFill="#256b51">
                     <font>
                        <Font name="Tahoma Bold" size="14.0" />
                     </font>
                  </Label>
                  <PasswordField fx:id="inpLoginSenha" layoutX="39.0" layoutY="225.0" prefHeight="30.0" prefWidth="220.0" promptText="Sua senha de 6 dígitos" styleClass="textfield" stylesheets="@lib/web/loginDesign.css" />
                  <Label layoutX="44.0" layoutY="200.0" text="Senha: " textFill="#256b51">
                     <font>
                        <Font name="Tahoma Bold" size="14.0" />
                     </font>
                  </Label>
                  <Button fx:id="loginBtn" layoutX="39.0" layoutY="327.0" mnemonicParsing="false" prefHeight="40.0" prefWidth="220.0" styleClass="login-btn" stylesheets="@lib/web/loginDesign.css" text="Entrar">
                     <font>
                        <Font name="Tahoma Bold" size="18.0" />
                     </font>
                  </Button>
                  <Button fx:id="close" layoutX="249.0" layoutY="1.0" mnemonicParsing="false" onAction="#close" prefHeight="26.0" prefWidth="44.0" />
                  <FontAwesomeIcon glyphName="CLOSE" layoutX="265.0" layoutY="18.0" size="1.3em" />
               </children>
            </AnchorPane>
         </children>
      </AnchorPane>
   </children>
</StackPane>

问题修复

核心原因

错误提示明确指向FXML文件未绑定控制器,尽管控制器类标注了@FxmlView,但结合FxWeaver与Spring的协作逻辑,需确保FXML与控制器的关联生效。

方案1:直接在FXML根节点指定控制器

修改login.fxml的<StackPane>根标签,添加fx:controller属性指定控制器全类名:

<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/20.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="br.edu.ifnmg.smrf.Apresentacao.Desktop.LoginController">

方案2:确保FxWeaver自动绑定生效

如果希望依赖@FxmlView自动关联,需检查Spring启动类的FxWeaver初始化逻辑:

@SpringBootApplication
public class SmrfApplication extends Application {

    private ConfigurableApplicationContext context;

    @Override
    public void init() throws Exception {
        context = SpringApplication.run(SmrfApplication.class);
    }

    @Override
    public void start(Stage stage) throws Exception {
        FxWeaver fxWeaver = context.getBean(FxWeaver.class);
        Parent root = fxWeaver.loadView(LoginController.class);
        stage.setScene(new Scene(root));
        stage.show();
    }

    @Override
    public void stop() throws Exception {
        context.close();
    }

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

此方式下需保证:

  • @FxmlView中的FXML路径与实际文件位置匹配(当前控制器与FXML同包,路径"login.fxml"正确)
  • pom.xml已引入FxWeaver依赖:net.rgielen:fxweaver-spring-boot-starter

额外修复点

FXML中close按钮绑定了onAction="#close",但控制器中无对应方法,需补充:

@FXML
public void close(ActionEvent e) {
    Platform.exit();
}

避免后续触发方法找不到的异常。

内容的提问来源于stack exchange,提问作者CAPETA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 00:23:11