1.创建SpringBoot项目
到 https://start.spring.io/ 创建一个SpringBoot2.1.x项目,解压后使用MyEclipse2015导入为maven项目~
2.引入JavaFX
对SpringBoot入口程序Application进行改造,继承javafx的application类,并引入接口CommandLineRunner, Consumer<Stage>,接着加入如下代码(高亮部分):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
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加入如下依赖:
1 2 3 4 5 6 7 |
<!-- 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用于展示欢迎界面,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
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()前面加入如下代码:
1 2 |
MainApplication.splashStage.hide(); MainApplication.splashStage.setScene(null); |
然后注释掉原来的application启动类中的main方法:
1 2 3 |
/*public static void main(String[] args) { SpringApplication.run(DgzqApplication.class, args); }*/ |
最后启动刚刚新建的MainApplication.java,便会出现中间界面:
好了,大功告成。如果还需要引入sqlite数据库,则可以继续往下操作。
4.引入hibernate并使用sqlite数据库
在MainApplication中的 下方加入如下代码,以提示sqlite是否存在:
1 2 3 4 5 6 7 8 |
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中加入如下依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
<!-- 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进行修改(加入高亮部分):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
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):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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中加入如下高亮代码
1 2 3 4 5 6 7 8 9 10 11 |
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.dgzq.MainApplication</mainClass> </configuration> </plugin> </plugins> </build> |
大功告成!