JavaFX + SQLite实现简单系统

学习来源

为了完成数据库大作业,终于开始了像蔡徐坤一样的学写代码的历程

首先在IDEA中新建一个javaFX项目,在sample文件夹会自动生成三个默认文件,删掉即可,新建自己的package和类

登录模块

在class上新建一个fxml文件,发现了什么不得了的东西。。好像是一个可拖拽的界面,看起来大有用处。

加载fxml文件:

1
2
3
4
5
6
7
8
public void start(Stage stage)throws Exception{
Parent root = (Parent) FXMLLoader.load(getClass().getResource("login.fxml"));

Scene scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("School Management System");
stage.show();
}

在fxml中拖入一个AnchorPane, 运行类就会出来一个窗口。

在fxml的源代码中添加控制器 fx:controller="loginapp.LoginController"

SQLiteStudio

下载地址

基本操作就不说了,图形化界面点点点就完事了。

新建一个dbUilt库,用于操作数据库。

连接数据库:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class dbConnection {
private static final String USERNAE = "dbuser";
private static final String PASSWORD = "dapassword";
private static final String CONN = "jdbc:mysql://localhost/login";
private static final String SQCONN = "jdbc:sqlite:schoolsystem.sqlite";

public static Connection getConnection() throws SQLException{
try{
Class.forName("org.sqlite.JDBC");
return DriverManager.getConnection(SQCONN);

} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
}

在fxml中,如果在使用中出现表格无法激活的情况,需要下载SceneBuilder, 并在IDEA的setting中指定JavaFX的路径到下载好的exe文件。然后就可以右键fxml文件 open in Scene Builder

这个功能更完善一点,可以搜索并配置controller,所以我还是下了一个。虽然下载速度很感人,看着YTB上的UP主秒打开链接我真的好羡慕啊。。

下载地址 还得注册一个oracle…账户 46…qq 密码 B…98 结果登不上..最后在网上找另一个可用的

注意在Scene Builder中修改完要保存一下。

拖入label,第一个命名,第二个设置为code对应的变量名。需要输入的拖入textfield。 password可以用专用PasswordField

拖入一个combobox,这是下拉框,在properties中添加 Admin/ Students, 作为选项,同样也可以在username的properties中甚至promot占位提示符。 还有一个button ,作为login键

为combobox添加枚举类型。

新建enum类option:

1
2
3
4
5
6
7
8
9
10
11
12
13
public enum option {
Admin,Student;

private option(){}

public String value(){
return name();
}

public static option fromvalue(String v){
return valueOf(v);
}
}

登录模块

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
public class LoginModel {
Connection connection;

public LoginModel(){
try {
this.connection = dbConnection.getConnection();

} catch (SQLException ex) {
ex.printStackTrace();
}
if(this.connection == null){
System.exit(1);
}
}

public boolean isDatabaseConnected(){
return this.connection != null;
}

public boolean isLogin(String user, String password, String opt)throws Exception{
PreparedStatement pr = null;
ResultSet rs = null;

String sql = "SELECT * FROM login where username = ? and password = ? and division = ?";

try{
pr = this.connection.prepareStatement(sql);
pr.setString(1,user);
pr.setString(2,password);
pr.setString(3,opt);

rs = pr.executeQuery();

boolean boll1;

if(rs.next()){
return true;
}
return false;
} catch (SQLException ex) {
return false;
}

finally {
{
pr.close();
rs.close();
}
}
}
}

控制模块:

注意在Label时要选择sence里的(因为很多库都有这个,不要弄错了)

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
public class LoginController implements Initializable {

LoginModel loginModel = new LoginModel();

@FXML
private Label dbstatus;
@FXML
private TextField username;
@FXML
private PasswordField password;
@FXML
private ComboBox<option> combobox;
@FXML
private Button loginButton;
public void initialize(URL url, ResourceBundle rb){
if(this.loginModel.isDatabaseConnected()){
this.dbstatus.setText("Connected to database");
}else{
this.dbstatus.setText("Not connected to database");
}

this.combobox.setItems(FXCollections.observableArrayList(option.values()));
}

}

运行时报错,java.lang.ClassNotFoundException: org.sqlite.JDBC没有安装sqlite的driver

下载地址 实在下不动,换了另一个网站

添加库:文件 -> 目录结构 -> 库 -> + java -> 下载的包

运行成功。

分用户登录

给Login键添加事件onaction。注意ActionEvent要选 javafx.event.

给admin和student分别写方法

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
@FXML
public void Login(ActionEvent event) {
try {
if (this.loginModel.isLogin(this.username.getText(), this.password.getText(), ((option) this.combobox.getValue()).toString())) {
Stage stage = (Stage) this.loginButton.getScene().getWindow();
stage.close();
switch (((option) this.combobox.getValue()).toString()) {
case "Admin":
adminLogin();
break;

case "Student":
studentLogin();
break;
}
}
else {
this.loginStatus.setText("Wrong Credential");
}
}catch(Exception localException){

}

}

public void studentLogin(){
try {
Stage userStage = new Stage();
FXMLLoader loader = new FXMLLoader();
Pane root = (Pane) loader.load(getClass().getResource("/students/studentFXML.fxml").openStream());

StudentsController studentsController = (StudentsController) loader.getController();

Scene scene = new Scene(root);
userStage.setScene(scene);
userStage.setTitle("Student Dashboard");
userStage.setResizable(false);
userStage.show();
} catch (IOException ex) {
ex.printStackTrace();
}
}

public void adminLogin(){
try {
Stage adminStage = new Stage();
FXMLLoader adminLoader = new FXMLLoader();
Pane adminroot = (Pane) adminLoader.load(getClass().getResource("/Admin/Admin.fxml").openStream());

AdminController adminController = (AdminController) adminLoader.getController();

Scene scene = new Scene(adminroot);
adminStage.setScene(scene);
adminStage.setTitle("Admin Dashboard");
adminStage.setResizable(false);
adminStage.show();
} catch (IOException ex) {
ex.printStackTrace();
}
}

这里数据连接有点问题。。不管了先学用法吧

设置Admin.fxml 。tabpane可以创建多标签的表格;右边添加Hbox;添加tableview,按需要添加列;左边添加Vbox,在里面添加所需的label可以设置padding,添加textfield可以设置margin;添加datapicker

在scene builder中可以预览效果

添加数据更新方法。在变量上右键可以快速生成get和set方法

数据加载:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private void loadStudentData(ActionEvent event)throws SQLException{
try{
Connection conn = dbConnection.getConnection();
this.data = FXCollections.observableArrayList();

ResultSet rs = conn.createStatement().executeQuery(sql);
while(rs.next()){
this.data.add(new StudentData(rs.getString(1),rs.getString(2),rs.getString(3),rs.getString(4),rs.getString(5)));
}
}catch (SQLException e){
System.err.println("ERROR"+ e );
}

this.idcolumn.setCellValueFactory(new PropertyValueFactory<StudentData,String>("id"));
this.fnamecolumn.setCellValueFactory(new PropertyValueFactory<StudentData,String>("fname"));
this.lnamecolumn.setCellValueFactory(new PropertyValueFactory<StudentData,String>("lname"));
this.emailcolumn.setCellValueFactory(new PropertyValueFactory<StudentData,String>("email"));
this.dobcolumn.setCellValueFactory(new PropertyValueFactory<StudentData,String>("dob"));

this.studenttable.setItems(null);
this.studenttable.setItems(this.data);
}

添加元组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private void addStudent(ActionEvent event){
String sqlInsert = "INSERT INTO students(id,fname,lname,email,dob) VALUES (?,?,?,?,?)";

try{
Connection conn = dbConnection.getConnection();
PreparedStatement stmt = conn.prepareStatement(sqlInsert);

stmt.setString(1,this.id.getText());
stmt.setString(2,this.fname.getText());
stmt.setString(3,this.lname.getText());
stmt.setString(4,this.email.getText());
stmt.setString(5,this.dob.getEditor().getText());

stmt.execute();
conn.close();

} catch (SQLException e) {
e.printStackTrace();
}
}

清空数据:

1
2
3
4
5
6
7
8
@FXML
private void clearFields(ActionEvent event){
this.id.setText("");
this.fname.setText("");
this.lname.setText("");
this.email.setText("");
this.dob.setValue(null);
}

生成jar: 文件 -> 项目结构 -> Artifacts ->jar ->from mode…depen..-> 选择LoginAPP作为入口类 -> build artifacts。 数据和jar要放在同一目录下才可以直接运行。

为避免JRE版本不一致,可以把jar转成exe


学完这个视频内容之后,最后用时三天总算写完了数据库大作业,不过冗余代码好多,我的OOP水平是真的烂啊..