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>
大功告成!