美文网首页
SpringBoot整合JavaFx、Jfoenix开发一个简单

SpringBoot整合JavaFx、Jfoenix开发一个简单

作者: 程就人生 | 来源:发表于2020-06-20 21:48 被阅读0次

    在上一篇文章中,IntelliJ IDEA的开发环境已经安装好了,现在就来一个简单的demo。想一想实际的应用场景,一般的桌面应用,都是需要经过登录页面,登录过后进入主页面;所以现在就做个简单的登录页面,登录过后跳转至主页面;下面上代码。

    首先,pom文件引入必要的架包;

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.4.RELEASE</version>
            <relativePath /> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.example.app</groupId>
        <artifactId>JavaFx-First</artifactId>
        <version>1.0-SNAPSHOT</version>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <java.version>1.8</java.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
            <!--字体架包-->
            <dependency>
                <groupId>de.jensd</groupId>
                <artifactId>fontawesomefx</artifactId>
                <version>8.9</version>
            </dependency>
            <dependency>
                <groupId>org.controlsfx</groupId>
                <artifactId>controlsfx</artifactId>
                <version>8.40.14</version>
            </dependency>
            <!---->
            <dependency>
                <groupId>com.jfoenix</groupId>
                <artifactId>jfoenix</artifactId>
                <version>8.0.7</version>
            </dependency>
        </dependencies>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    

    第二步,入口文件;

    package com.example.app;
    
    import com.example.app.controller.LoginController;
    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    
    /**
     * 入口程序
     * @author 程就人生
     * @Date
     */
    public class MyApp extends Application {
    
        //主窗口
        private Stage mainStage;
    
        @Override
        public void start(Stage primaryStage) throws Exception{
            mainStage = primaryStage;
            //加载登录页面
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/login.fxml"));
            Parent root = loader.load();
            LoginController controller = loader.getController();
            controller.setApp(this);
            Scene scene = new Scene(root);
            //设置样式
            //scene.getStylesheets().add(getClass().getResource("/css/jfoenix-components.css").toExternalForm());
            //绑到顶层容器上
            primaryStage.setScene(scene);
            //设置标题
            primaryStage.setTitle("第一个JavaFx程序");
            //展示窗口
            primaryStage.show();
        }
    
        /**
         * 隐藏当前窗口
         */
        public void hideWindow(){
            mainStage.hide();
        }
    }
    

    第三,fxml文件;
    登录login.fxml文件;

    <?import com.jfoenix.controls.JFXButton?>
    <?import com.jfoenix.controls.JFXPasswordField?>
    <?import com.jfoenix.controls.JFXTextField?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.layout.AnchorPane?>
    
    <AnchorPane prefHeight="400.0" prefWidth="464.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.app.controller.LoginController">
       <children>
          <JFXButton fx:id="loginButton" layoutX="167.0" layoutY="262.0" mnemonicParsing="false" onMouseClicked="#login" prefHeight="30.0" prefWidth="202.0" styleClass="button-raised" text="登录" />
          <JFXPasswordField fx:id="password" layoutX="167.0" layoutY="200.0" promptText="请输入密码" />
          <JFXTextField fx:id="username" layoutX="167.0" layoutY="136.0" promptText="请输入用户名" />
          <Label layoutX="113.0" layoutY="141.0" text="用户名" />
          <Label layoutX="113.0" layoutY="205.0" text="密码" />
       </children>
    </AnchorPane>
    

    主页面main.fxml文件;

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.control.Button?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.layout.AnchorPane?>
    
    <AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.app.controller.MainController">
       <children>
          <Label layoutX="66.0" layoutY="149.0" prefHeight="132.0" prefWidth="457.0" text="这里是主页面" />
          <Button layoutX="147.0" layoutY="266.0" mnemonicParsing="false" text="Button" />
       </children>
    </AnchorPane>
    

    第四,Controller文件;
    登录LoginController文件;

    package com.example.app.controller;
    
    import com.example.app.MyApp;
    import com.jfoenix.controls.JFXButton;
    import com.jfoenix.controls.JFXPasswordField;
    import com.jfoenix.controls.JFXTextField;
    import javafx.fxml.FXML;
    import javafx.fxml.FXMLLoader;
    import javafx.fxml.Initializable;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.scene.control.Alert;
    import javafx.stage.Stage;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringUtils;
    
    import java.io.IOException;
    import java.net.URL;
    import java.util.ResourceBundle;
    
    /**
     *
     * 登录
     * @author 程就人生
     * @Date
     */
    @Component
    public class LoginController implements Initializable {
    
        @FXML
        JFXTextField username;
    
        @FXML
        JFXPasswordField password;
    
        @FXML
        JFXButton loginButton;
    
        private MyApp myApp;
    
        public void setApp(MyApp myApp) {
            this.myApp = myApp;
        }
    
        /**
         * 初始化方法
         * @param location
         * @param resources
         */
        @Override
        public void initialize(URL location, ResourceBundle resources) {
    
        }
    
        /**
         * 登录操作
         */
        @FXML
        public void login(){
            //验证用户名是否为空
            if(StringUtils.isEmpty(username.getText())){
                Alert alert = new Alert(Alert.AlertType.ERROR);
                alert.setContentText("用户名不能为空!");
                alert.show();
                return;
            }
            if(StringUtils.isEmpty(password.getText())){
                Alert alert = new Alert(Alert.AlertType.ERROR);
                alert.setContentText("密码不能为空!");
                alert.show();
                return;
            }
            myApp.hideWindow();
            //加载登录页面
            FXMLLoader loader = new FXMLLoader(myApp.getClass().getResource("/main.fxml"));
            Parent root = null;
            try {
                root = loader.load();
            } catch (IOException e) {
                e.printStackTrace();
            }
            MainController controller = loader.getController();
            controller.setApp(myApp);
            //开启一个顶级容器
            Stage stage = new Stage();
            controller.setStage(stage);
            Scene scene = new Scene(root);
            stage.setScene(scene);
            //设置标题
            stage.setTitle("登录后的主页面");
            //展示窗口
            stage.show();
        }
    }
    

    主页面MainController文件;

    package com.example.app.controller;
    
    import com.example.app.MyApp;
    import javafx.fxml.Initializable;
    import javafx.stage.Stage;
    import org.springframework.stereotype.Component;
    import java.net.URL;
    import java.util.ResourceBundle;
    
    /**
     * 主页面
     * @author 程就人生
     * @Date
     */
    @Component
    public class MainController implements Initializable {
    
        private MyApp myApp;
    
        private Stage stage;
    
        public void setApp(MyApp myApp) {
            this.myApp = myApp;
        }
    
        public void setStage(Stage _stage){
            this.stage = _stage;
        }
    
        /**
         * 初始化方法
         * @param location
         * @param resources
         */
        @Override
        public void initialize(URL location, ResourceBundle resources) {
    
        }
    }
    

    最后,测试;
    运行主文件,输入用户名密码,页面跳转;

    登录页面
    登录后的主页面

    框架里引入了Jfoenix框架后,页面已经有一点样式了,不像原生的swing组件那么粗糙,如果想要漂亮一点的UI,还需要继续学习这几款框架是如何使用的。

    一个应用只有一个入口程序,入口程序继承了Application抽象类,通过重写start方法启动了主程序,抽象类里有两种主题,还有两个launch抽象方法,init、start、stop等方法。

    
    public abstract class Application {
        //两种主题
        public static final String STYLESHEET_CASPIAN = "CASPIAN";
     
        public static final String STYLESHEET_MODENA = "MODENA";
        //运行方法
        public static void launch(Class<? extends Application> appClass, String... args) {
            LauncherImpl.launchApplication(appClass, args);
        }
    
        public static void launch(String... args) {
            // Figure out the right class to call
            StackTraceElement[] cause = Thread.currentThread().getStackTrace();
    
            boolean foundThisMethod = false;
            String callingClassName = null;
            for (StackTraceElement se : cause) {
                // Skip entries until we get to the entry for this class
                String className = se.getClassName();
                String methodName = se.getMethodName();
                if (foundThisMethod) {
                    callingClassName = className;
                    break;
                } else if (Application.class.getName().equals(className)
                        && "launch".equals(methodName)) {
    
                    foundThisMethod = true;
                }
            }
    
            if (callingClassName == null) {
                throw new RuntimeException("Error: unable to determine Application class");
            }
    
            try {
                Class theClass = Class.forName(callingClassName, false,
                                   Thread.currentThread().getContextClassLoader());
                if (Application.class.isAssignableFrom(theClass)) {
                    Class<? extends Application> appClass = theClass;
                    LauncherImpl.launchApplication(appClass, args);
                } else {
                    throw new RuntimeException("Error: " + theClass
                            + " is not a subclass of javafx.application.Application");
                }
            } catch (RuntimeException ex) {
                throw ex;
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }
    
        public Application() {
        }
       //初始化抽象方法
        public void init() throws Exception {
        }
        //开始抽象方法;
        public abstract void start(Stage primaryStage) throws Exception;
        
        public void stop() throws Exception {
        }
    
        private HostServices hostServices = null;
    
        public final HostServices getHostServices() {
            synchronized (this) {
                if (hostServices == null) {
                    hostServices = new HostServices(this);
                }
                return hostServices;
            }
        }
    
        public final Parameters getParameters() {
            return ParametersImpl.getParameters(this);
        }
       
        public final void notifyPreloader(PreloaderNotification info) {
            LauncherImpl.notifyPreloader(this, info);
        }
     
        public static abstract class Parameters {
          
            public Parameters() {
            }
    
            public abstract List<String> getRaw();
    
            public abstract List<String> getUnnamed();
    
          
            public abstract Map<String, String> getNamed();
    
        }
    
        private static String userAgentStylesheet = null;
    
        public static String getUserAgentStylesheet() {
            return userAgentStylesheet;
        }
    
        public static void setUserAgentStylesheet(String url) {
            userAgentStylesheet = url;
            if (url == null) {
                PlatformImpl.setDefaultPlatformUserAgentStylesheet();
            } else {
                PlatformImpl.setPlatformUserAgentStylesheet(url);
            }
        }
    }
    

    另外还有一个非常非常重要的类,那就是Stage,该类继续了Window类,该类是顶级的JavaFX容器,要打开一个窗口,必须有Stage类做底层容器。所以,从登陆页面到主页面,又新new了一个stage,来放置主页面的一系列组件。

    这是第一个JavaFx的简单应用,通过拖拽的方式生成了登录页面和主页面,也遇到了一些问题,想必其他的新手也会遇到;那就是在拖拽的过程中,控件的id在一开始时是这样写的id="username",结果导致控制层的username.getText()一直报空指针错误,把id="username"改为fx:id="username"之后,就可以正常运行了。

    相关文章

      网友评论

          本文标题:SpringBoot整合JavaFx、Jfoenix开发一个简单

          本文链接:https://www.haomeiwen.com/subject/ubggxktx.html