1.创建SpringBoot项目
到 https://start.spring.io/ 创建一个SpringBoot2.1.x项目,解压后使用MyEclipse2015导入为maven项目~
2.引入JavaFX
对SpringBoot入口程序Application进行改造,继承javafx的application类,并引入接口CommandLineRunner, Consumer<Stage>,接着加入如下代码(高亮部分):
package com.dgzq; import java.util.function.Consumer; import javafx.application.Application; import javafx.application.Platform; import javafx.scene.Scene; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import javafx.scene.control.TabPane.TabClosingPolicy; import javafx.stage.Stage; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DgzqApplication extends Application implements CommandLineRunner, Consumer<Stage>{ public static void main(String[] args) { SpringApplication.run(DgzqApplication.class, args); } @Override public void run(String... args) throws Exception { Platform.runLater(new Runnable() { @Override public void run() { Stage stage = new Stage(); try { start(stage); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } @Override public void start(Stage primaryStage) throws Exception { accept(primaryStage); } @Override public void accept(Stage stage) { TabPane tabPane = new TabPane(); //增加标签面板 tabPane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE); Scene scene = new Scene(tabPane, 900, 690); stage.setScene(scene); stage.setTitle("测试界面"); Tab tab1 = new Tab("标签页1"); Tab tab2 = new Tab("标签页2"); tabPane.getTabs().addAll(tab1,tab2); tabPane.getSelectionModel().select(tab1); //设置默认选中 stage.show(); } }
然后启动,出现如下界面则为成功:
3.增加预加载页面
在pom.xml加入如下依赖:
<!-- SpringBoot2.x与JavaFX的集成 --> <!-- https://mvnrepository.com/artifact/de.roskenet/springboot-javafx-support --> <dependency> <groupId>de.roskenet</groupId> <artifactId>springboot-javafx-support</artifactId> <version>2.1.6</version> </dependency>
新增一个启动入口文件如MainApplication.java用于展示欢迎界面,代码如下:
package com.dgzq; import java.io.File; import org.springframework.boot.autoconfigure.SpringBootApplication; import de.felixroske.jfxsupport.AbstractJavaFxApplicationSupport; import de.felixroske.jfxsupport.SplashScreen; import javafx.scene.Scene; import javafx.scene.control.Alert; import javafx.stage.Stage; import javafx.stage.StageStyle; import javafx.scene.paint.Color; @SpringBootApplication public class MainApplication extends AbstractJavaFxApplicationSupport { public static SplashScreen splashScreen; public static Stage splashStage; public static Scene splashScene; public static void main(String[] args) { //启动(若需要以fxml形式展示主界面,则第二个传参可以为"MainStageView.class"之类的) launch(MainApplication.class, null, args); } @Override public void start(Stage stage) throws Exception { MainApplication.splashScreen = new SplashScreen(); MainApplication.splashStage = new Stage(StageStyle.TRANSPARENT); MainApplication.splashScene = new Scene(splashScreen.getParent(), Color.TRANSPARENT); MainApplication.splashStage.setScene(splashScene); MainApplication.splashStage.initStyle(StageStyle.TRANSPARENT); MainApplication.splashStage.show(); } }
在预加载完成后还要再正式界面中隐藏掉本界面,因此要在原来的application类的stage.show()前面加入如下代码:
MainApplication.splashStage.hide(); MainApplication.splashStage.setScene(null);
然后注释掉原来的application启动类中的main方法:
/*public static void main(String[] args) { SpringApplication.run(DgzqApplication.class, args); }*/
最后启动刚刚新建的MainApplication.java,便会出现中间界面:
好了,大功告成。如果还需要引入sqlite数据库,则可以继续往下操作。
4.引入hibernate并使用sqlite数据库
在MainApplication中的 下方加入如下代码,以提示sqlite是否存在:
File databaseFile = new File("sqlite3.db"); if(!databaseFile.exists()){ Alert alert = new Alert(Alert.AlertType.INFORMATION); alert.setTitle("错误"); alert.setHeaderText(null); alert.setContentText("找不到数据库文件:sqlite3.db(本次运行将自动创建全新的空白数据库)"); alert.showAndWait(); }
再pom.xml中加入如下依赖:
<!-- sqlite3驱动包 --> <!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc --> <dependency> <groupId>org.xerial</groupId> <artifactId>sqlite-jdbc</artifactId> <version>3.28.0</version> </dependency> <!-- SpringBoot与hibernate的集成配置 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- SpringBoot使用Hibernate的SessionFactory --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.0.12.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>5.0.12.Final</version> </dependency> <!-- SpringBoot2.x与JavaFX的集成 --> <!-- https://mvnrepository.com/artifact/de.roskenet/springboot-javafx-support --> <dependency> <groupId>de.roskenet</groupId> <artifactId>springboot-javafx-support</artifactId> <version>2.1.6</version> </dependency>
对原来的Application进行修改(加入高亮部分):
package com.dgzq; import java.util.function.Consumer; import javafx.application.Application; import javafx.application.Platform; import javafx.scene.Scene; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import javafx.scene.control.TabPane.TabClosingPolicy; import javafx.stage.Stage; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.orm.jpa.vendor.HibernateJpaSessionFactoryBean; @SpringBootApplication public class DgzqApplication extends Application implements CommandLineRunner, Consumer<Stage>{ public static SessionFactory sessionFactory; @Autowired public void setSessionFactory(SessionFactory sessionFactory) { DgzqApplication.sessionFactory = sessionFactory; } @Bean public HibernateJpaSessionFactoryBean sessionFactory() { return new HibernateJpaSessionFactoryBean(); } /*public static void main(String[] args) { SpringApplication.run(DgzqApplication.class, args); }*/ @Override public void run(String... args) throws Exception { Platform.runLater(new Runnable() { @Override public void run() { Stage stage = new Stage(); try { start(stage); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } @Override public void start(Stage primaryStage) throws Exception { accept(primaryStage); } @Override public void accept(Stage stage) { System.out.println("MainJavaFxApplication被实例化了"); System.out.println("MainJavaFxApplication.sessionFactory = "+sessionFactory); TabPane tabPane = new TabPane(); //增加标签面板 tabPane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE); Scene scene = new Scene(tabPane, 900, 690); stage.setScene(scene); stage.setTitle("测试界面"); Tab tab1 = new Tab("标签页1"); Tab tab2 = new Tab("标签页2"); tabPane.getTabs().addAll(tab1,tab2); tabPane.getSelectionModel().select(tab1); //设置默认选中 MainApplication.splashStage.hide(); MainApplication.splashStage.setScene(null); stage.show(); } }
增加sqlite的方言类SQLiteDialect.java:
package com.fenji; import java.sql.Types; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.function.StandardSQLFunction; import org.hibernate.dialect.function.SQLFunctionTemplate; import org.hibernate.dialect.function.VarArgsSQLFunction; import org.hibernate.type.StandardBasicTypes; public class SQLiteDialect extends Dialect { public SQLiteDialect() { super(); registerColumnType(Types.BIT, "integer"); registerColumnType(Types.TINYINT, "tinyint"); registerColumnType(Types.SMALLINT, "smallint"); registerColumnType(Types.INTEGER, "integer"); registerColumnType(Types.BIGINT, "bigint"); registerColumnType(Types.FLOAT, "float"); registerColumnType(Types.REAL, "real"); registerColumnType(Types.DOUBLE, "double"); registerColumnType(Types.NUMERIC, "numeric"); registerColumnType(Types.DECIMAL, "decimal"); registerColumnType(Types.CHAR, "char"); registerColumnType(Types.VARCHAR, "varchar"); registerColumnType(Types.LONGVARCHAR, "longvarchar"); registerColumnType(Types.DATE, "date"); registerColumnType(Types.TIME, "time"); registerColumnType(Types.TIMESTAMP, "timestamp"); registerColumnType(Types.BINARY, "blob"); registerColumnType(Types.VARBINARY, "blob"); registerColumnType(Types.LONGVARBINARY, "blob"); // registerColumnType(Types.NULL, "null"); registerColumnType(Types.BLOB, "blob"); registerColumnType(Types.CLOB, "clob"); registerColumnType(Types.BOOLEAN, "integer"); registerFunction("concat", new VarArgsSQLFunction(StandardBasicTypes.STRING, "", "||", "")); registerFunction("mod", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "?1 % ?2")); registerFunction("substr", new StandardSQLFunction("substr", StandardBasicTypes.STRING)); registerFunction("substring", new StandardSQLFunction("substr", StandardBasicTypes.STRING)); } public boolean supportsIdentityColumns() { return true; } public boolean hasDataTypeInIdentityColumn() { return false; } public String getIdentityColumnString() { return "integer"; } public String getIdentitySelectString() { return "select last_insert_rowid()"; } public boolean supportsLimit() { return true; } public String getLimitString(String query, boolean hasOffset) { return new StringBuffer(query.length() + 20).append(query).append(hasOffset ? " limit ? offset ?" : " limit ?") .toString(); } public boolean supportsTemporaryTables() { return true; } public String getCreateTemporaryTableString() { return "create temporary table if not exists"; } public boolean dropTemporaryTableAfterUse() { return false; } public boolean supportsCurrentTimestampSelection() { return true; } public boolean isCurrentTimestampSelectStringCallable() { return false; } public String getCurrentTimestampSelectString() { return "select current_timestamp"; } public boolean supportsUnionAll() { return true; } public boolean hasAlterTable() { return false; } public boolean dropConstraints() { return false; } public String getAddColumnString() { return "add column"; } public String getForUpdateString() { return ""; } public boolean supportsOuterJoinForUpdate() { return false; } public String getDropForeignKeyString() { throw new UnsupportedOperationException("No drop foreign key syntax supported by SQLiteDialect"); } public String getAddForeignKeyConstraintString(String constraintName, String[] foreignKey, String referencedTable, String[] primaryKey, boolean referencesPrimaryKey) { throw new UnsupportedOperationException("No add foreign key syntax supported by SQLiteDialect"); } public String getAddPrimaryKeyConstraintString(String constraintName) { throw new UnsupportedOperationException("No add primary key syntax supported by SQLiteDialect"); } public boolean supportsIfExistsBeforeTableName() { return true; } public boolean supportsCascadeDelete() { return false; } @Override public boolean bindLimitParametersInReverseOrder() { return true; } }
增加配置文件application.properties用于配置数据库(注意高亮行,要指向刚刚创建的方言类SQLiteDialect.java):
spring.datasource.driver-class-name=org.sqlite.JDBC spring.datasource.url=jdbc:sqlite:sqlite3.db # Specify the DBMS #spring.jpa.database=SQLite # Show or not log for each sql query spring.jpa.show-sql=true # Hibernate ddl auto (create, create-drop, update) spring.jpa.hibernate.ddl-auto=update # Naming strategy spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy # stripped before adding them to the entity manager #spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect spring.jpa.properties.hibernate.dialect=com.dgzq.SQLiteDialect # table column upcase problem spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl # auto inject sessionFactory bean spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
好了,运行MainApplication看看效果:
如图所示,输入sessionFactory不为空,则注入成功,后面大家自由发挥吧!
5.补充:记得指定maven打包时的启动入口
在pom.xml中加入如下高亮代码
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.dgzq.MainApplication</mainClass> </configuration> </plugin> </plugins> </build>
大功告成!