使用JDBC+javafx写一个简单功能齐全的图书管理系统

news2024/11/24 9:47:56

目录

1、JDBC的使用

 2、对应包和Java文件的层级关系及对应的含义

3、数据库

4、相关代码

1)、bookmanager包

Ⅰ、main函数

Ⅱ、utils包

Ⅲ、bean包 

Ⅳ、controller包 

 2)resources(为资源文件包,可以看链接文章了解)

Ⅰ、book包

Ⅱ、 login包

5、效果展示(对应功能实现在相应代码中)

1)、登录功能

 2)、注册功能

 3)、后台主页面

 4)、修改密码页

 5)注销页​​​​​​​

在文章结尾有图书管理系统的效果展示

1、JDBC的使用

后面会用到大量jdbc语句来实现数据库的增删改查,可以先简单看看下面这篇文章。

jdbc的简单使用与封装

 2、对应包和Java文件的层级关系及对应的含义

 上面DBUtils为jdbc的封装,详情可以看jdbc的简单使用与封装,还有dp.properties文件也在这篇文章中收到,我后面就不再过多概述。

3、数据库

admin:

book:

 category:

4、相关代码

1)、bookmanager包

Ⅰ、main函数

BookManagerApplication

package com.hk.sky.bookmanager;

import com.hk.sky.bookmanager.bean.Admin;
import com.hk.sky.bookmanager.controller.LoginController;
import com.hk.sky.bookmanager.dao.AdminDao;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;


public class BookManagerApplication extends Application {
    AdminDao adminDao=new AdminDao();
    //获取上一次用户登录的信息
    Admin admin=adminDao.getLast();
    @Override
    public void start(Stage stage) throws IOException {
        //登录页面的资源文件为login/login.fxml
        FXMLLoader fxmlLoader = new FXMLLoader(BookManagerApplication.class.getResource("login/login.fxml"));
        //设置登录窗口的长和宽
        Scene scene = new Scene(fxmlLoader.load(), 290, 240);
        stage.setTitle("管理员登录");
        stage.setScene(scene);
        LoginController loginController=fxmlLoader.getController();
        //如果admin不是为null,则说明上一次有用户登录,则直接在登录页面显示账号和密码
        if (admin!=null)
            loginController.set(admin.getAccount(),admin.getPassword());
        stage.show();
    }
    //启动
    public static void main(String[] args) {
        launch();
    }
}

Ⅱ、utils包

DBUtils

package com.hk.sky.bookmanager.utils;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;

/**
 * 封装数据连接,关闭的工具类
 */
public class DBUtils {

    private static String url;
    private static String username;
    private static String password;

    // 读取配置文件
    static {
        Properties prop = new Properties();

        try {
            // DBUtils.class.getClassLoader().getResourceAsStream()方法可以从类路径中读取资源文件
            prop.load(DBUtils.class.getClassLoader().getResourceAsStream("db.properties"));

            // 通过key获取value
            url = prop.getProperty("jdbc.url");
            username = prop.getProperty("jdbc.username");
            password = prop.getProperty("jdbc.password");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    // 将创建连接的方法封装成静态方法,方便调用
    // 如何将url、username、password放到配置文件当中,然后读取出来
    public static Connection getConnection() {
        // 创建连接的时候,有会异常:SQLException,不建议抛出,建立捕获
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(
                    url,
                    username,
                    password
            );
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return conn;
    }
    
    // 将关闭连接的方法封装成静态方法,方便调用
    public static void close(ResultSet rs, PreparedStatement pStmt, Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (pStmt != null) {
            try {
                pStmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

Ⅲ、bean包 

Admin

package com.hk.sky.bookmanager.bean;

public class Admin {
    //账号
    private String account;
    //密码
    private String password;
    //上一次登录
    private int last;

    public String getAccount() {
        return account;
    }

    public String getPassword() {
        return password;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getLast() {
        return last;
    }

    public void setLast(int last) {
        this.last = last;
    }

    @Override
    public String toString() {
        return "Admin{" +
                "account='" + account + '\'' +
                ", password='" + password + '\'' +
                ", last=" + last +
                '}';
    }
}

book

package com.hk.sky.bookmanager.bean;

public class Book {
    private int id;
    private String bookName;
    private String author;
    private int price;
    private int stock;
    private String publisher;
    private String detail;
    private int typeId;

    public void setDetail(String detail) {
        this.detail = detail;
    }
    public String getDetail() {
        return detail;
    }

    public int getId() {
        return id;
    }

    public String getBookName() {
        return bookName;
    }

    public String getAuthor() {
        return author;
    }

    public int getPrice() {
        return price;
    }

    public int getStock() {
        return stock;
    }

    public String getPublisher() {
        return publisher;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public void setStock(int stock) {
        this.stock = stock;
    }

    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }

    public void setTypeId(int typeId) {
        this.typeId = typeId;
    }

    public int getTypeId() {
        return typeId;
    }
    public Book(){}
    public Book(String name, String author, String publisher, int price, String detail, int stock, int typeId) {
        this.bookName = name;
        this.author = author;
        this.publisher = publisher;
        this.price = price;
        this.detail = detail;
        this.stock = stock;
        this.typeId = typeId;
    }
}

Category

package com.hk.sky.bookmanager.bean;

public class Category {
    private int id;
    private String typeName;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTypeName() {
        return typeName;
    }

    public void setTypeName(String typeName) {
        this.typeName = typeName;
    }

    @Override
    public String toString() {
        return typeName;
    }
}

Ⅳ、controller包 

AddController

package com.hk.sky.bookmanager.controller;

import com.hk.sky.bookmanager.bean.Book;
import com.hk.sky.bookmanager.bean.Category;
import com.hk.sky.bookmanager.dao.BookDao;
import com.hk.sky.bookmanager.dao.CategoryDao;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.stage.Stage;

import java.net.URL;
import java.sql.SQLException;
import java.util.*;


public class AddController implements Initializable {
    @FXML
    public Button add;
    @FXML
    public Button edit;

    @FXML
    private ComboBox<Category> categoryComboBox;

    private ObservableList<Category> observableList = FXCollections.observableArrayList();

    private CategoryDao categoryDao = new CategoryDao();

    private BookDao bookDao = new BookDao();

    @FXML
    private TextField bookName;
    @FXML
    private TextField bookAuthor;
    @FXML
    private TextField bookPublisher;
    @FXML
    private TextField bookPrice;
    @FXML
    private TextField detail;
    @FXML
    private TextField bookStock;
    public Book book;

    public void setBook(Book book) {
        this.book = book;
    }
    //B用来判断是添加书籍还是编辑书籍
    public boolean B;
    public void setB(boolean i){
        this.B=i;
    }
    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        Platform.runLater(() -> {
            // 页面第一次加载的时候,就显示下拉列表
            observableList.clear();
            List<Category> categories = categoryDao.getAllCategories();
            observableList.addAll(categories);
            categoryComboBox.setItems(observableList);
            //添加书籍  修改书籍
            if (B){
                add.setVisible(true);
                add.setText("添加");
                edit.setVisible(false);
                edit.setText("");
                categoryComboBox.setValue(categories.get(0));
            }else {
                bookName.setText(book.getBookName());
                bookAuthor.setText(book.getAuthor());
                bookPublisher.setText(book.getPublisher());
                bookPrice.setText(String.valueOf(book.getPrice()));
                detail.setText(book.getDetail());
                bookStock.setText(String.valueOf(book.getStock()));
                categoryComboBox.setValue(categories.get(book.getTypeId()));
                edit.setVisible(true);
                edit.setText("修改");
                add.setDisable(false);
                add.setText("");
            }
        });
    }
    //给添加按钮设置点击事件
    public void addBook() throws SQLException {
        // 用户点击添加按钮时,获取所有的数据,并插入到数据库当中
        String name = bookName.getText();
        String author = bookAuthor.getText();
        String publisher = bookPublisher.getText();
        String detail1 = detail.getText();

        // 将格式进行转换
        // 表单验证,判断用户是否输入内容
        if (name.equals("") || author.equals("") || publisher.equals("") || detail1.equals("") ||
                bookPrice.getText().equals("") || bookStock.getText().equals("")) {

            Alert error = new Alert(Alert.AlertType.ERROR, "输入错误");
            Button err = new Button();
            error.setTitle("您的书籍信息输入错误!");
            error.setHeaderText("请正确填写所要添加书籍的信息!");
            err.setOnAction((ActionEvent e) -> {
                error.showAndWait();
            });
            Optional<ButtonType> result = error.showAndWait();
        } else if (!bookPrice.getText().matches("[1-9]+[0-9]*")||!bookStock.getText().matches("[1-9]+[0-9]*")){
            Alert error = new Alert(Alert.AlertType.ERROR, "输入错误");
            Button err = new Button();
            error.setTitle("您的书籍信息输入错误!");
            error.setHeaderText("库存和价格必须为整数!");
            err.setOnAction((ActionEvent e) -> {
                error.showAndWait();
            });
            Optional<ButtonType> result = error.showAndWait();
        }else{
            // 思路:将上面获取到的数据封装成book,然后插入到数据库当中
            // 但是仔细思考,我们会碰到一个难点:如何获取ComboBox的选项?也就是说如何知道用户选的是哪一个类型的书籍?
            Category selectedCategory = categoryComboBox.getValue();
            int price = Integer.parseInt(bookPrice.getText());
            int stock = Integer.parseInt(bookStock.getText());

            // 将所有的数据封装成书籍
            Book book = new Book(name, author, publisher, price, detail1, stock, selectedCategory.getId());
            // 调用BookDao中的方法将数据插入到数据库当中
            Alert information = new Alert(Alert.AlertType.INFORMATION, "恭喜您书籍添加成功");
            Button err = new Button();
            information.setTitle("添加成功!");
            information.setHeaderText("林氏图书馆又收录了一本新书,感谢!");
            err.setOnAction((ActionEvent e) -> {
                information.showAndWait();
            });
            Optional<ButtonType> result = information.showAndWait();

            // 插入成功之后,首先当前属性应该关闭
            if (bookDao.insertBook(book)){
                ((Stage) bookName.getScene().getWindow()).close();
            }
        }
    }
    //给编辑按钮设置点击事件
    public void editBook(ActionEvent actionEvent) throws SQLException{
        // 用户点击添加按钮时 ,获取所有的数据,并插入到数据库当中
        String name = bookName.getText();
        String author = bookAuthor.getText();
        String publisher = bookPublisher.getText();
        String detail1 = detail.getText();

        // 将格式进行转换
        // 表单验证,判断用户是否输入内容
        if (name.equals("")||author.equals("")||publisher.equals("")||detail1.equals("")||
                bookPrice.getText().equals("")||bookStock.getText().equals("")){

            Alert error=new Alert(Alert.AlertType.ERROR,"输入错误");
            Button err=new Button();
            error.setTitle("您的书籍信息输入错误!");
            error.setHeaderText("请正确填写所要修改书籍的信息!");
            err.setOnAction((ActionEvent e)->{
                error.showAndWait();
            });
            Optional<ButtonType> result = error.showAndWait();
        }else if (!bookPrice.getText().matches("[1-9]+[0-9]*")||!bookStock.getText().matches("[1-9]+[0-9]*")){
            Alert error = new Alert(Alert.AlertType.ERROR, "输入错误");
            Button err = new Button();
            error.setTitle("您的书籍信息输入错误!");
            error.setHeaderText("库存和价格必须为整数!");
            err.setOnAction((ActionEvent e) -> {
                error.showAndWait();
            });
            Optional<ButtonType> result = error.showAndWait();
        }else {
            int price = Integer.parseInt(bookPrice.getText());
            int stock = Integer.parseInt(bookStock.getText());

            // 思路:将上面获取到的数据封装成book,然后插入到数据库当中
            // 但是仔细思考,我们会碰到一个难点:如何获取ComboBox的选项?也就是说如何知道用户选的是哪一个类型的书籍?
            Category selectedCategory = categoryComboBox.getValue();

            // 将所有的数据封装成书籍
            Book book1 = new Book(name, author, publisher, price, detail1, stock, selectedCategory.getId());
            book1.setId(book.getId());
            // 调用BookDao中的方法将数据插入到数据库当中
            Alert information=new Alert(Alert.AlertType.INFORMATION,"恭喜您书籍信息修改成功");
            Button err=new Button();
            information.setTitle("修改成功!");
            information.setHeaderText("谢谢您为林氏图书馆添砖加瓦,感谢!");
            err.setOnAction((ActionEvent e)->{
                information.showAndWait();
            });
            Optional<ButtonType> result = information.showAndWait();
            boolean success = bookDao.updateBook(book1);
            // 插入成功之后,首先当前属性应该关闭
            if (success) {
                ((Stage)bookName.getScene().getWindow()).close();
            }
        }
    }
}

 EnrollController

package com.hk.sky.bookmanager.controller;

import com.hk.sky.bookmanager.bean.Admin;
import com.hk.sky.bookmanager.dao.AdminDao;
import com.hk.sky.bookmanager.utils.DBUtils;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.text.Text;
import javafx.stage.Stage;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Objects;
import java.util.Optional;

public class EnrollController {
    @FXML
    public TextField username1;
    @FXML
    public PasswordField password1;
    @FXML
    public Text errorMsg;//提示错误信息
    @FXML
    private Button alert;
    @FXML
    private Button enroll;
    @FXML
    public Text title;
    AdminDao adminDao=new AdminDao();

    //给注册按钮设置点击事件
    public void enrollBtn() {
        String account=username1.getText();
        String pw=password1.getText();

        if (Objects.equals(account, "")){
            errorMsg.setText("请填写用户名");
        }else if (Objects.equals(pw, "")){
            errorMsg.setText("请填写密码");
        }else {
            boolean b=adminDao.enroll(account,pw);
            if(!b){
                errorMsg.setText("用户名已使用,请更改用户名!");
            }else {
                Alert information=new Alert(Alert.AlertType.INFORMATION,"恭喜"+account+"用户注册成功");
                Button err=new Button();
                information.setTitle("注册成功!");
                information.setHeaderText("林氏图书馆欢迎您的到来!");
                err.setOnAction((ActionEvent e)->{
                    information.showAndWait();
                });
                Optional<ButtonType> result = information.showAndWait();
                // 关闭当前Stage,问题:如何获取当前的stage?
                Stage currentWindow = (Stage)username1.getScene().getWindow();
                currentWindow.close();
            }

        }
    }

    //区分是注册还是修改密码,修改密码的话账号无法更改,输入框为不可选择,注册按钮消失,修改按钮显示
    public void qf(boolean b){
        if (b){
            enroll.setVisible(false);
            alert.setVisible(true);

            username1.setDisable(true);
        }
    }
    //s用来保存原密码,修改密码无法更改为原密码
    public String s;
    public void setS(String ss){
        s=ss;
    }
    //给修改密码设置点击事件
    public void alertBtn() throws SQLException {
        if (password1.getText().equals("")){
            errorMsg.setText("密码不能为空");
        }else if(password1.getText().equals(s)){
            errorMsg.setText("不能与最近使用密码相同");
        }else {
            Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "你是否真的要修改该密码?");
            alert.setTitle("修改密码");
            alert.setHeaderText("确认修改?");
            Optional<ButtonType> result = alert.showAndWait();
            if (result.isPresent()){
                adminDao.alertPassword(username1.getText(),password1.getText());
                Alert information = new Alert(Alert.AlertType.INFORMATION, "恭喜您修改密码成功!");
                Button err = new Button();
                information.setTitle("修改密码");
                information.setHeaderText("修改密码成功!");
                err.setOnAction((ActionEvent e) -> {
                    information.showAndWait();
                });
                Optional<ButtonType> rs = information.showAndWait();
            }
        }
    }
}

 HouTaiController

package com.hk.sky.bookmanager.controller;

import com.hk.sky.bookmanager.BookManagerApplication;
import com.hk.sky.bookmanager.bean.Admin;
import com.hk.sky.bookmanager.bean.Book;
import com.hk.sky.bookmanager.dao.AdminDao;
import com.hk.sky.bookmanager.dao.BookDao;
import javafx.application.Platform;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.text.Text;
import javafx.stage.Stage;

import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.ResourceBundle;

public class HouTaiController implements Initializable {
    /*搜索框*/
    public TextField search;
    /*下拉框*/
    public ComboBox categorySelect;

    // 不能直接从这里查询用户信息,因为在当前这个类当中,我不知道是谁登录了
    // 通过上一个类传递到当前类当中,我们需要在当前类中定义要传递的数据,然后通过set方法设置该属性的值
    private Admin admin;
    public String bookName;
    public String bookAuthor;
    public String Publish;
    //表示查询到的行
    public int sumPage;
    //n表示页数
    public int n;
    public void setAdmin(Admin admin) {
        this.admin = admin;
    }
    public void setSumPage(int i){
        this.sumPage=i;
        double j=i/9.0;
        n=(int) Math.ceil(j);
    }
    public void setBookName(String s){
        bookName=s;
    }
    @FXML
    private Text welcomeMsg;
    @FXML
    private Text searchCount;
    @FXML
    private Text searchPage;
    @FXML//返回按钮
    private Button fh;
    //给表添加数据
    @FXML
    private TableView<Book> bookTable;
    // 准备表格中的数据
    private ObservableList<Book> data = FXCollections.observableArrayList();
    // 准备dao类,它负责到数据库中查询
    private BookDao bookDao = new BookDao();
    private AdminDao adminDao=new AdminDao();
    //添加按钮操作
    // 编辑按钮
    private TableColumn<Book, Integer> editColumn = new TableColumn<>("编辑");

    // 删除按钮
    private TableColumn<Book, Integer> delColumn = new TableColumn<>("删除");

    // 详情按钮
    private TableColumn<Book, Integer> detailColumn = new TableColumn<>("详情");


    // 上一个页面中将admin传递过来,我们需要在当前窗口中来获取传递过来的数据,然后将值设置给页面中的元素显示
    // 将当前类实现Initializable接口,然后在initialize(初始化)方法中获取设置的值,然后设置给页面中的元素
    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        // 通过UI线程获取值,并设置值
        Platform.runLater(() -> {
            welcomeMsg.setText("欢迎" + admin.getAccount() + "管理员登录!");
            searchCount.setText("共"+sumPage+"条记录");
            categorySelect.getItems().addAll(
                    "书名",
                    "出版社",
                    "作者"
            );
            categorySelect.setValue("书名");
            // 查询数据库,设置ObservableList,并添加至tableView当中
            List<Book> books = bookDao.set(search.getText(),0);
            data.addAll(books);
            bookTable.setItems(data);

            //1、添加编辑按钮
            editColumn.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue().getId()));
            editColumn.setCellFactory(param -> new TableCell<>(){
                final Button editBtn = new Button("编辑");
                @Override
                protected void updateItem(Integer item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item == null) {
                        setGraphic(null);
                        return;
                    }
                    setGraphic(editBtn);
                    // 添加点击事件
                    editBtn.setOnMouseClicked(event ->{
                        try {
                            Stage newStage = new Stage();
                            FXMLLoader fxmlLoader = new FXMLLoader(BookManagerApplication.class.getResource("book/add.fxml"));
                            Scene scene = new Scene(fxmlLoader.load(), 280, 400);
                            newStage.setTitle("编辑书籍");
                            newStage.setScene(scene);
                            AddController addController=fxmlLoader.getController();
                            addController.setB(false);
                            addController.setBook(bookDao.getbookById(item));
                            newStage.show();
                            // 我们需要监听添加页面关闭后,刷新tableview
                            // CloseRequest()只有在用户点击右上角的叉时才会触发
                            newStage.setOnHiding(evt->{
                                refreshTableView(i);
                            });
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }

                    });
                }
            });
            //将列添加至表中
            bookTable.getColumns().add(editColumn);

            //2、添加删除按钮
            delColumn.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue().getId()));
            delColumn.setCellFactory(param -> new TableCell<>(){
                // 创建删除按钮
                final Button editBtn = new Button("删除");

                @Override
                protected void updateItem(Integer item, boolean empty) {
                    super.updateItem(item, empty);
                    if (item == null) {
                        setGraphic(null);
                        return;
                    }
                    setGraphic(editBtn);

                    // 添加点击事件
                    editBtn.setOnMouseClicked(event -> {
                        // 添加一个对话框,判断用户是否需要真的删除
                        Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "你是否需要真的删除这本吗?");
                        alert.setTitle("警告");
                        alert.setHeaderText("确认删除?");
                        Optional<ButtonType> result = alert.showAndWait();

                        if (result.isPresent() && result.get() == ButtonType.OK) {
                            // 实现删除功能
                            bookDao.deleteBookById(item);
                            // 刷新页面
                            refreshTableView(i);
                        }
                    });

                }
            });
            //将列添加至表中
            bookTable.getColumns().add(delColumn);

            // 3、添加详情按钮
            detailColumn.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue().getId()));
            detailColumn.setCellFactory(param -> new TableCell<>(){
                // 创建详情按钮
                final Button editBtn = new Button("详情");
                @Override
                protected void updateItem (Integer item,boolean empty){
                    super.updateItem(item, empty);
                    if (item == null) {
                        setGraphic(null);
                        return;
                    }
                    setGraphic(editBtn);

                    // 添加点击事件
                    editBtn.setOnMouseClicked(event -> {
                        try {
                            Stage newStage = new Stage();
                            FXMLLoader fxmlLoader = new FXMLLoader(BookManagerApplication.class.getResource("book/show.fxml"));
                            Scene scene = new Scene(fxmlLoader.load(), 280, 270);
                            newStage.setTitle("书籍详情");
                            newStage.setScene(scene);

                            // 将当前书籍id传递到下一个页面当中
                            ShowController showController = fxmlLoader.getController();
                            showController.setBook(bookDao.getbookById(item));

                            // 显示要打开的Stage,stage.show()
                            newStage.show();
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    });
                    //将列添加至表中
                }
            });
            bookTable.getColumns().add(detailColumn);
        });
    }

    public void refreshTableView(int i){
        // 在往集合中添加数据之前,先清空集合
        data.clear();

        List<Book> books = null;
        // 查询数据库,设置ObservableList,并添加至tableView当中
        if(categorySelect.getValue().equals("作者")&&bookAuthor!=null) {
            setSumPage(bookDao.likeSumCountByAuthor(search.getText()));
            if (i==n)
                i--;
            books= bookDao.setByAuthor(bookAuthor, i);
            searchCount.setText("共"+bookDao.likeSumCountByAuthor(search.getText())+"条记录");
        }else if (categorySelect.getValue().equals("出版社")&&Publish!=null){
            setSumPage(bookDao.likeSumCountByPublish(search.getText()));
            if (i==n)
                i--;
            books= bookDao.setByPublish(Publish, i);
            searchCount.setText("共"+bookDao.likeSumCountByPublish(search.getText())+"条记录");
        }else {
            setSumPage(bookDao.likeSumCount(search.getText()));
            if (i==n)
                i--;
            books= bookDao.set(bookName, i);
            searchCount.setText("共"+bookDao.likeSumCount(search.getText())+"条记录");

        }

        data.addAll(books);
        bookTable.setItems(data);

        int z=i+1;
        searchPage.setText("第"+z+"页");
    }

    int i=0;
    //首页按钮
    public void start(){
        if (i!=0){
            data.clear();
            List<Book> books=null;
            // 查询数据库,设置ObservableList,并添加至tableView当中
            if (categorySelect.getValue().equals("出版社")&&Publish!=null){
                books=bookDao.setByPublish(Publish,0);
            }else if (categorySelect.getValue().equals("作者")&&bookAuthor!=null){
                books=bookDao.setByAuthor(bookAuthor,0);
            }else {
                books= bookDao.set(bookName,0);
            }

            data.addAll(books);
            bookTable.setItems(data);
            i=0;
            searchPage.setText("第"+1+"页");
        }
    }
    //尾页按钮
    public void end(){
        if (i!=n-1){
            data.clear();
            List<Book> books=null;
            // 查询数据库,设置ObservableList,并添加至tableView当中
            // 查询数据库,设置ObservableList,并添加至tableView当中
            if (categorySelect.getValue().equals("出版社")&&Publish!=null){
                books=bookDao.setByPublish(Publish,n-1);
            }else if (categorySelect.getValue().equals("作者")&&bookAuthor!=null){
                books=bookDao.setByAuthor(bookAuthor,n-1);
            }else {
                books= bookDao.set(bookName,n-1);
            }

            data.addAll(books);
            bookTable.setItems(data);
            i=n-1;
            searchPage.setText("第"+n+"页");
        }
    }
    //上一页按钮
    public void up(){
        if (i>0&&i<=n-1){
            data.clear();
            // 查询数据库,设置ObservableList,并添加至tableView当中
            List<Book> books=null;
            // 查询数据库,设置ObservableList,并添加至tableView当中
            if (categorySelect.getValue().equals("出版社")&&Publish!=null){
                books=bookDao.setByPublish(Publish,--i);
            }else if (categorySelect.getValue().equals("作者")&&bookAuthor!=null){
                books=bookDao.setByAuthor(bookAuthor,--i);
            }else {
                books= bookDao.set(bookName,--i);
            }
            data.addAll(books);
            bookTable.setItems(data);
            int z=i+1;
            searchPage.setText("第"+z+"页");
        }
    }
    //下一页按钮
    public void next(){
        if (i<n-1&&i>=0){
            data.clear();
            // 查询数据库,设置ObservableList,并添加至tableView当中
            List<Book> books=null;
            // 查询数据库,设置ObservableList,并添加至tableView当中
            if (categorySelect.getValue().equals("出版社")&&Publish!=null){
                books=bookDao.setByPublish(Publish,++i);
            }else if (categorySelect.getValue().equals("作者")&&bookAuthor!=null){
                books=bookDao.setByAuthor(bookAuthor,++i);
            }else {
                books= bookDao.set(bookName,++i);
            }
            data.addAll(books);
            bookTable.setItems(data);
            int z=i+1;
            searchPage.setText("第"+z+"页");
        }
    }
    //搜索按钮
    public void searchBtn() throws IOException {
       if (categorySelect.getValue().equals("书名")){
        if (!Objects.equals(search.getText(), "")){
            if (bookDao.likeSumCount(search.getText())==0){
                Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "抱歉,为查找到有关该图书!");
                alert.setTitle("查找错误");
                alert.setHeaderText("请重新填写所要查找书籍的名称!");
                Optional<ButtonType> result = alert.showAndWait();
            }else {
                fh.setVisible(true);
                bookName=search.getText();
                // 在往集合中添加数据之前,先清空集合
                data.clear();
                // 查询数据库,设置ObservableList,并添加至tableView当中
                List<Book> books = bookDao.set(bookName,0);
                data.addAll(books);
                bookTable.setItems(data);
                setSumPage(bookDao.likeSumCount(bookName));
                searchCount.setText("共"+bookDao.likeSumCount(search.getText())+"条记录");
                i=0;
                searchPage.setText("第"+1+"页");
            }
        }else {
            Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "错误,搜索框中未输入查询数据!");
            alert.setTitle("输入错误");
            alert.setHeaderText("请填写所要查找书籍的名称,书籍名不能为空!");
            Optional<ButtonType> result = alert.showAndWait();
        }
       }else if (categorySelect.getValue().equals("作者")){
           if (!Objects.equals(search.getText(), "")){
               if (bookDao.likeSumCountByAuthor(search.getText())==0){
                   Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "抱歉,未查找到有关该图书!");
                   alert.setTitle("查找错误");
                   alert.setHeaderText("请重新填写所要查找书籍的作者!");
                   Optional<ButtonType> result = alert.showAndWait();
               }else {
                   fh.setVisible(true);
                   bookAuthor=search.getText();
                   // 在往集合中添加数据之前,先清空集合
                   data.clear();
                   // 查询数据库,设置ObservableList,并添加至tableView当中
                   List<Book> books = bookDao.setByAuthor(bookAuthor,0);
                   data.addAll(books);
                   bookTable.setItems(data);
                   setSumPage(bookDao.likeSumCountByAuthor(bookAuthor));
                   searchCount.setText("共"+bookDao.likeSumCountByAuthor(bookAuthor)+"条记录");
                   i=0;
                   searchPage.setText("第"+1+"页");
               }
           }else {
               Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "错误,搜索框中未输入查询数据!");
               alert.setTitle("输入错误");
               alert.setHeaderText("请填写所要查找书籍的作者,作者名不能为空!");
               Optional<ButtonType> result = alert.showAndWait();
           }
       }else {
           if (!Objects.equals(search.getText(), "")){
               if (bookDao.likeSumCountByPublish(search.getText())==0){
                   Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "抱歉,未查找到有关该图书!");
                   alert.setTitle("查找错误");
                   alert.setHeaderText("请重新填写所要查找书籍的出版社!");
                   Optional<ButtonType> result = alert.showAndWait();
               }else {
                   fh.setVisible(true);
                   Publish=search.getText();
                   // 在往集合中添加数据之前,先清空集合
                   data.clear();
                   // 查询数据库,设置ObservableList,并添加至tableView当中
                   List<Book> books = bookDao.setByPublish(Publish,0);
                   data.addAll(books);
                   bookTable.setItems(data);
                   setSumPage(bookDao.likeSumCountByPublish(Publish));
                   searchCount.setText("共"+bookDao.likeSumCountByPublish(Publish)+"条记录");
                   i=0;
                   searchPage.setText("第"+1+"页");
               }
           }else {
               Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "错误,搜索框中未输入查询数据!");
               alert.setTitle("输入错误");
               alert.setHeaderText("请填写所要查找书籍的出版社,出版社名不能为空!");
               Optional<ButtonType> result = alert.showAndWait();
           }
       }
    }
    //删除按钮
    public void deleteBtn() {
        Book book1=null;
        String bookName=search.getText();
        book1=bookDao.getBookByBookName(bookName);
        if (book1!=null){
            // 添加一个对话框,判断用户是否需要真的删除
            Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "你是否需要真的删除这本书吗?");
            alert.setTitle("警告");
            alert.setHeaderText("确认删除?");
            Optional<ButtonType> result = alert.showAndWait();

            if (result.isPresent() && result.get() == ButtonType.OK) {
                // 实现删除功能
                bookDao.deleteBookByBookName(bookName);
                // 刷新页面
                refreshTableView(i);
            }
        }else {
            // 添加一个对话框,告诉用户没有这本书
            Alert error=new Alert(Alert.AlertType.ERROR,"删除错误,该图书馆未收录此书!");
            Button err=new Button();
            error.setTitle("删除错误!");
            error.setHeaderText("请重新填写要删除的书籍!");
            err.setOnAction((ActionEvent e)->{
                error.showAndWait();
            });
            Optional<ButtonType> result = error.showAndWait();
        }
    }
    //添加按钮
    public void addBtn()  {
        try {
            Stage newStage = new Stage();
            FXMLLoader fxmlLoader = new FXMLLoader(BookManagerApplication.class.getResource("book/add.fxml"));
            Scene scene = new Scene(fxmlLoader.load(), 280, 400);
            newStage.setTitle("添加书籍");
            newStage.setScene(scene);
            AddController addController=fxmlLoader.getController();
            addController.setB(true);

            newStage.show();
            // 我们需要监听添加页面关闭后,刷新tableview
            // CloseRequest()只有在用户点击右上角的叉时才会触发
            newStage.setOnHiding(event -> {
                refreshTableView(i);
            });
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
    //返回按钮
    public void back(ActionEvent actionEvent) {
        categorySelect.setValue("书名");
        search.setText("");
        bookName=search.getText();
        // 在往集合中添加数据之前,先清空集合
        data.clear();
        // 查询数据库,设置ObservableList,并添加至tableView当中
        List<Book> books = bookDao.set(bookName,0);
        data.addAll(books);
        bookTable.setItems(data);
        setSumPage(bookDao.likeSumCount(bookName));
        searchCount.setText("共"+bookDao.likeSumCount(search.getText())+"条记录");
        i=0;
        searchPage.setText("第"+1+"页");
        fh.setVisible(false);
    }
    //注销按钮
    public void zx(ActionEvent actionEvent) throws IOException {
        Alert alert = new Alert(Alert.AlertType.CONFIRMATION, "你是否真的要注销该账号?");
        alert.setTitle("警告");
        alert.setHeaderText("确认注销?");
        Optional<ButtonType> result = alert.showAndWait();
        if (result.isPresent() && result.get() == ButtonType.OK) {
            adminDao.delete(admin.getAccount());
            //提醒用户该账号已注销,请重新登录
            Alert information = new Alert(Alert.AlertType.INFORMATION, "该账号已注销!");
            Button err = new Button();
            information.setTitle("登录失败!");
            information.setHeaderText("该账号已注销,请重新登录");
            err.setOnAction((ActionEvent e) -> {
                information.showAndWait();
            });
            Optional<ButtonType> result1 = information.showAndWait();

            //关闭 后台 页面
            Stage currentWindow = (Stage)search.getScene().getWindow();
            currentWindow.close();

            //重新显示登录页面
            Stage stage = new Stage();
            FXMLLoader fxmlLoader = new FXMLLoader(BookManagerApplication.class.getResource("login/login.fxml"));
            Scene scene = new Scene(fxmlLoader.load(), 290, 240);
            stage.setTitle("用户登录");
            stage.setScene(scene);

            stage.show();
        }
    }
    //修改密码
    public void xgmm(ActionEvent actionEvent) throws IOException {
        Stage stage = new Stage();
        FXMLLoader fxmlLoader = new FXMLLoader(BookManagerApplication.class.getResource("login/enroll.fxml"));
        Scene scene = new Scene(fxmlLoader.load(), 290, 251);
        stage.setTitle("修改密码");
        stage.setScene(scene);
        EnrollController enrollController=fxmlLoader.getController();
        enrollController.username1.setText(admin.getAccount());
        enrollController.password1.setText(admin.getPassword());
        String s=admin.getPassword();
        enrollController.title.setText("修改密码");
        enrollController.setS(admin.getPassword());

        enrollController.qf(true);
        stage.show();
        //添加监听事件,检查密码是否更换
        stage.setOnHiding(evt -> {
            try {
                if (adminDao.checkPassword(admin.getAccount(),s)){
                    Alert information = new Alert(Alert.AlertType.INFORMATION, "该账号已注销!");
                    Button err = new Button();
                    information.setTitle("登录失败!");
                    information.setHeaderText("该账号已注销,请重新登录");
                    err.setOnAction((ActionEvent e) -> {
                        information.showAndWait();
                    });
                    Optional<ButtonType> result1 = information.showAndWait();

                    //关闭 后台 页面
                    Stage currentWindow = (Stage)search.getScene().getWindow();
                    currentWindow.close();

                    //重新显示登录页面
                    Stage stage1 = new Stage();
                    FXMLLoader fxmlLoader1 = new FXMLLoader(BookManagerApplication.class.getResource("login/login.fxml"));
                    Scene scene1 = new Scene(fxmlLoader1.load(), 290, 240);
                    stage1.setTitle("用户登录");
                    stage1.setScene(scene1);
                    LoginController loginController=fxmlLoader1.getController();
                    loginController.username.setText(admin.getAccount());
                    stage1.show();
                    adminDao.reset();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });

    }
}

LoginController

package com.hk.sky.bookmanager.controller;

import com.hk.sky.bookmanager.BookManagerApplication;
import com.hk.sky.bookmanager.bean.Admin;
import com.hk.sky.bookmanager.dao.AdminDao;
import com.hk.sky.bookmanager.dao.BookDao;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.text.Text;
import javafx.stage.Stage;

import java.io.IOException;

public class LoginController {

    @FXML
    public TextField username;

    @FXML
    private PasswordField password;

    @FXML
    private Text errorMsg;
    //设置上一次登录账号的账号密码
    public void set(String un,String pw){
        if (un!=null&&pw!=null){
            username.setText(un);
            password.setText(pw);
        }
    }

    @FXML
    //登录按钮 检查是否有该账号以及账号密码的正确性
    public void checkLogin() throws IOException {
        // 获取输入框中的内容
        String uname = username.getText();
        String pwd = password.getText();

        // 判断用户名与密码
        AdminDao adminDao = new AdminDao();
        Admin admin = adminDao.checkLogin(uname, pwd);
        if (admin == null) {
            errorMsg.setText("用户名或者密码错误");
        } else {
            // 跳转到后面页面
            // 创建要打开的Stage,问题:stage如何创建?
            Stage newStage = new Stage();
            FXMLLoader fxmlLoader = new FXMLLoader(BookManagerApplication.class.getResource("book/houtai.fxml"));
            Scene scene = new Scene(fxmlLoader.load(), 700, 430);
            newStage.setTitle("后台页面");
            newStage.setScene(scene);

            // 关闭当前Stage,问题:如何获取当前的stage?
            Stage currentWindow = (Stage) username.getScene().getWindow();
            currentWindow.close();
            //消除上次用户登录的信息
            adminDao.reset();
            //保存这次用户登录的信息
            adminDao.setLast(username.getText());

            // 将当前用户的信息传递到下一个页面当中
            HouTaiController houTaiController = fxmlLoader.getController();
            BookDao bookdao=new BookDao();
            houTaiController.setSumPage(bookdao.sumPage());
            houTaiController.setAdmin(admin);
            houTaiController.setBookName("");

            // 显示要打开的Stage,stage.show()
            newStage.show();
        }
    }
    //注册按钮
    public void enrollLogin() throws IOException{
        Stage stage = new Stage();
        FXMLLoader fxmlLoader = new FXMLLoader(BookManagerApplication.class.getResource("login/enroll.fxml"));
        Scene scene = new Scene(fxmlLoader.load(), 290, 251);
        stage.setTitle("用户注册");
        stage.setScene(scene);
        stage.show();
    }
}

 ShowController

package com.hk.sky.bookmanager.controller;

import com.hk.sky.bookmanager.bean.Book;
import com.hk.sky.bookmanager.dao.BookDao;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.text.Text;

import java.net.URL;
import java.util.ResourceBundle;

public class ShowController implements Initializable {
    @FXML
    public Text bookId;
    Book book=null;
    public void setBook(Book book1){
        this.book=book1;
    }
    private BookDao bookDao = new BookDao();

    @FXML
    private Text bookName;
    @FXML
    private Text bookAuthor;
    @FXML
    private Text bookPublish;
    @FXML
    private Text bookPrice;
    @FXML
    private Text bookStock;
    @FXML
    private Text bookDetail;

    //书籍详情页面显示
    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        Platform.runLater(() -> {
            bookId.setText(String.valueOf(book.getId()));
            bookName.setText(book.getBookName());
            bookAuthor.setText(book.getAuthor());
            bookPublish.setText(book.getPublisher());
            bookPrice.setText(String.valueOf(book.getPrice()));
            bookStock.setText(String.valueOf(book.getStock()));
            bookDetail.setText(book.getDetail());
        });
    }
}

module-info

module com.example.bookmange {
    requires javafx.controls;
    requires javafx.fxml;
    requires javafx.web;

    requires org.controlsfx.controls;
    requires validatorfx;
    requires org.kordamp.ikonli.javafx;
    requires org.kordamp.bootstrapfx.core;
    requires eu.hansolo.tilesfx;
    requires java.sql;

    opens com.hk.sky.bookmanager to javafx.fxml;
    exports com.hk.sky.bookmanager;
    exports com.hk.sky.bookmanager.controller;
    opens com.hk.sky.bookmanager.controller to javafx.fxml;
    opens com.hk.sky.bookmanager.bean to javafx.base;
}

 2)resources(为资源文件包,可以看链接文章了解)

Ⅰ、book包

add.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.text.Text?>
<?import java.net.URL?>
<GridPane xmlns="http://javafx.com/javafx"
          xmlns:fx="http://javafx.com/fxml"
          fx:controller="com.hk.sky.bookmanager.controller.AddController"
          prefHeight="400.0" prefWidth="600.0" hgap="20" vgap="20">

    <padding>
        <Insets left="20" top="30"/>
    </padding>

    <Text text="类型:" GridPane.rowIndex="0" GridPane.columnIndex="0"/>
    <ComboBox  GridPane.halignment="CENTER" GridPane.rowIndex="0" GridPane.columnIndex="1" fx:id="categoryComboBox">
    </ComboBox>

    <Text text="书名:" GridPane.rowIndex="1" GridPane.columnIndex="0"/>
    <TextField fx:id="bookName" GridPane.rowIndex="1" GridPane.columnIndex="1"/>

    <Text text="作者:" GridPane.rowIndex="2" GridPane.columnIndex="0"/>
    <TextField fx:id="bookAuthor" GridPane.rowIndex="2" GridPane.columnIndex="1"/>

    <Text text="出版社:" GridPane.rowIndex="3" GridPane.columnIndex="0"/>
    <TextField fx:id="bookPublisher" GridPane.rowIndex="3" GridPane.columnIndex="1"/>

    <Text text="价格:" GridPane.rowIndex="4" GridPane.columnIndex="0"/>
    <TextField fx:id="bookPrice" GridPane.rowIndex="4" GridPane.columnIndex="1"/>

    <Text text="内容简介:" GridPane.rowIndex="5" GridPane.columnIndex="0"/>
    <TextField fx:id="detail" GridPane.rowIndex="5" GridPane.columnIndex="1"/>

    <Text text="库存:" GridPane.rowIndex="6" GridPane.columnIndex="0"/>
    <TextField fx:id="bookStock" GridPane.rowIndex="6" GridPane.columnIndex="1"/>

    <Button fx:id="add" text="添加" onAction="#addBook" GridPane.rowIndex="7" GridPane.columnIndex="0" GridPane.columnSpan="2"
            GridPane.halignment="CENTER" styleClass="aBtn" visible="true" > </Button>

    <Button fx:id="edit" onAction="#editBook" GridPane.rowIndex="7" GridPane.columnIndex="0" GridPane.columnSpan="2"
            GridPane.halignment="CENTER" styleClass="eBtn" visible="false"> </Button>
    <stylesheets>
        <URL value="@add.css"/>
    </stylesheets>

</GridPane>

 houtai.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<?import javafx.scene.text.Text?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.cell.PropertyValueFactory?>
<?import java.net.URL?>
<AnchorPane xmlns="http://javafx.com/javafx"
            xmlns:fx="http://javafx.com/fxml"
            fx:controller="com.hk.sky.bookmanager.controller.HouTaiController"
            prefHeight="550.0" prefWidth="580.0" styleClass="ht">


    <Button fx:id="fh" text="返回" visible="false" onAction="#back"/>

    <Text id="wm" fx:id="welcomeMsg" AnchorPane.leftAnchor="290" AnchorPane.topAnchor="10"/>

    <Button  text="修改密码"  onAction="#xgmm" AnchorPane.leftAnchor="585"/>
    <Button  text="注销"  onAction="#zx" AnchorPane.leftAnchor="658"/>

    <HBox AnchorPane.leftAnchor="180" AnchorPane.topAnchor="35">
        <ComboBox    fx:id="categorySelect">
        </ComboBox>
        <TextField fx:id="search">
            <HBox.margin>
                <Insets left="10" />
            </HBox.margin>
        </TextField>

        <Button text="查询" onAction="#searchBtn">
            <HBox.margin>
                <Insets left="10" right="10"/>
            </HBox.margin>
        </Button>

        <Button text="删除" onAction="#deleteBtn">
            <HBox.margin>
                <Insets right="10"/>
            </HBox.margin>
        </Button>

        <Button text="添加" onAction="#addBtn">
        </Button>
    </HBox>

    <TableView styleClass="table-view"
               fx:id="bookTable" AnchorPane.leftAnchor="10" AnchorPane.topAnchor="70" prefHeight="287" prefWidth="680">
        <columns>
            <TableColumn text="编号" prefWidth="40">
                <cellValueFactory>
                    <PropertyValueFactory property="id"/>
                </cellValueFactory>
            </TableColumn>

            <TableColumn text="书名"  prefWidth="100">
                <cellValueFactory>
                    <PropertyValueFactory property="bookName"/>
                </cellValueFactory>
            </TableColumn>

            <TableColumn text="作者">
                <cellValueFactory>
                    <PropertyValueFactory property="author"/>
                </cellValueFactory>
            </TableColumn>

            <TableColumn text="价格">
                <cellValueFactory>
                    <PropertyValueFactory property="price"/>
                </cellValueFactory>
            </TableColumn>

            <TableColumn text="库存">
                <cellValueFactory>
                    <PropertyValueFactory property="stock"/>
                </cellValueFactory>
            </TableColumn>

            <TableColumn text="出版社" prefWidth="130">
                <cellValueFactory>
                    <PropertyValueFactory property="publisher"/>
                </cellValueFactory>
            </TableColumn>
        </columns>
    </TableView>

    <FlowPane AnchorPane.leftAnchor="150" AnchorPane.bottomAnchor="20" hgap="20" alignment="CENTER">
        <Text fx:id="searchCount"/>
        <Text fx:id="searchPage" text="第1页"/>
        <Button onAction="#start" text="首页"/>
        <Button onAction="#up" text="上一页"/>
        <Button onAction="#next" text="下一页"/>
        <Button onAction="#end" text="尾页"/>
    </FlowPane>

    <stylesheets>
        <URL value="@houtai.css"/>
    </stylesheets>
</AnchorPane>

show.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.*?>

<?import javafx.scene.image.ImageView?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.text.Text?>
<?import javafx.geometry.Insets?>
<?import java.net.URL?>
<GridPane xmlns="http://javafx.com/javafx"
          xmlns:fx="http://javafx.com/fxml"
          fx:controller="com.hk.sky.bookmanager.controller.ShowController"
          hgap="8" vgap="8">

    <padding>
        <Insets left="10" top="20" />
    </padding>

    <ImageView GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.rowSpan="5" fitWidth="75" fitHeight="90">
        <Image url="@image/book.png" />
    </ImageView>

    <Text GridPane.rowIndex="0" GridPane.columnIndex="1" text="编号:"/>
    <Text fx:id="bookId" GridPane.rowIndex="0" GridPane.columnIndex="2"/>

    <Text GridPane.rowIndex="1" GridPane.columnIndex="1" text="书名:"/>
    <Text fx:id="bookName" GridPane.rowIndex="1" GridPane.columnIndex="2"/>

    <Text GridPane.rowIndex="2" GridPane.columnIndex="1" text="作者:"/>
    <Text fx:id="bookAuthor" GridPane.rowIndex="2" GridPane.columnIndex="2"/>

    <Text GridPane.rowIndex="3" GridPane.columnIndex="1" text="价格:"/>
    <Text fx:id="bookPrice" GridPane.rowIndex="3" GridPane.columnIndex="2"/>

    <Text GridPane.rowIndex="4" GridPane.columnIndex="1" text="库存:"/>
    <Text fx:id="bookStock" GridPane.rowIndex="4" GridPane.columnIndex="2"/>

    <Text GridPane.rowIndex="5" GridPane.columnIndex="1" text="出版社:"/>
    <Text fx:id="bookPublish" GridPane.rowIndex="5" GridPane.columnIndex="2"/>

    <Text GridPane.rowIndex="6" GridPane.columnIndex="0" text="详情" GridPane.halignment="CENTER" GridPane.columnSpan="3"
          styleClass="xq"/>
    <Text fx:id="bookDetail" GridPane.rowIndex="7" GridPane.columnIndex="0" GridPane.columnSpan="3" wrappingWidth="260"/>
    <stylesheets>
        <URL value="@show.css"/>
    </stylesheets>
</GridPane>

 add.css

.aBtn{
    -fx-background-color: #0274FE;
    -fx-pref-width: 80px;
    -fx-pref-height: 40px;
    -fx-background-radius: 10px;
    -fx-text-fill: #fff;
    /*鼠标在上面会变成手的形状*/
    -fx-cursor: hand;
    /*加粗*/
    -fx-font-weight:bold;
}
.eBtn{
    -fx-background-color: #0274FE;
    /*按钮长宽*/
    -fx-pref-width: 80px;
    -fx-pref-height: 40px;
    -fx-background-radius: 10px;
    /*设置文字颜色*/
    -fx-text-fill: #fff;
    -fx-cursor: hand;
}

houtai.css

#wm{
-fx-font-size: 14px;
-fx-font-family:"Microsoft YaHei UI";

}
.table-view .table-column{
  -fx-alignment:CENTER;
  -fx-font-weight:bold;
  /*点击文字会变色*/
  -fx-light-text-color:red;
}

.ht{
/*设置背景,其中链接为网络图像链接*/
-fx-background-image:url("https://b.zol-img.com.cn/desk/bizhi/image/10/960x600/1598319721647.jpg");
-fx-background-repeat:stretch;
-fx-background-size:700 430;
}
/*设置表格为透明,下面四个样式缺一不可*/
.table-view {
	-fx-background-color: transparent;
}
/*表格最上面一行导航栏设置透明*/
.table-column {
	-fx-background-color: transparent;
}
.table-view .column-header-background {
 	-fx-background-color:transparent;
 }
/*表格内容透明*/
.table-row-cell {
    -fx-background-color:transparent;
}

show.css

.xq{
-fx-font-size: 14px;
/*设置字体颜色*/
-fx-fill: RED;
}

 image大家可以在书籍模型图片中找,有很多种图片给大家选择

Ⅱ、 login包

login.css

#login-title {
    -fx-font-size: 26px;
    -fx-font-family: "Microsoft YaHei UI";
}

.login-btn {
    -fx-background-color: #0274FE;
    /*设置按钮长宽*/
    -fx-pref-width: 50px;
    -fx-pref-height: 30px;
    /*设置按钮角边距*/
    -fx-background-radius: 30px;
    -fx-text-fill: #fff;
    -fx-cursor: hand;
}
.enroll-btn {
    -fx-background-color: #0274FE;
    -fx-pref-width: 150px;
    -fx-pref-height: 30px;
    /*设置按钮角边距*/
    -fx-background-radius: 10px;
    -fx-text-fill: #fff;
    -fx-cursor: hand;
}
.login{
/*设置背景,其中链接为网络图像链接*/
-fx-background-image:url("https://ts1.cn.mm.bing.net/th/id/R-C.2007af8279430f7cdae54e3714cceeef?rik=E0YMmdkLdVaw8Q&riu=http%3a%2f%2f5b0988e595225.cdn.sohucs.com%2fimages%2f20181117%2f8e26ba707bf74f6bb8a87cf1a3f35ffb.gif&ehk=OBammaDlXjLLw29ouO%2b6nENFuzJNMOFwirTInUSCmfo%3d&risl=&pid=ImgRaw&r=0");
-fx-background-repeat:stretch;
-fx-background-size:290 240;
}
.enroll{
/*设置背景,其中链接为网络图像链接*/
-fx-background-image:url("https://ts1.cn.mm.bing.net/th/id/R-C.0bd134123caa7005ec50e75b45218a54?rik=lSaVSid3n%2bfrXg&riu=http%3a%2f%2fwww.kutoo8.com%2fupload%2fimage%2f81433892%2f12.jpg&ehk=cjol7ne5lTOk6iPRCR%2f2RIoGlffBEHdj9QO5RHUWYdk%3d&risl=&pid=ImgRaw&r=0");
-fx-background-repeat:stretch;
-fx-background-size:290 251;
}

 enroll.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>

<?import javafx.scene.control.Button?>


<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.text.Text?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.PasswordField?>
<?import java.net.URL?>
<GridPane fx:controller="com.hk.sky.bookmanager.controller.EnrollController"
          xmlns:fx="http://javafx.com/fxml" vgap="10" hgap="10" styleClass="enroll">

    <padding>
        <Insets top="40" left="30"/>
    </padding>

    <Text id="login-title" fx:id="title" text="注 册" GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2"
          GridPane.halignment="CENTER"/>

    <Label text="用户名:" GridPane.rowIndex="1" GridPane.columnIndex="0"/>

    <TextField fx:id="username1" GridPane.rowIndex="1" GridPane.columnIndex="1"/>

    <Label text="密码:" GridPane.rowIndex="2" GridPane.columnIndex="0"/>

    <PasswordField fx:id="password1" GridPane.rowIndex="2" GridPane.columnIndex="1"/>

    <Text fx:id="errorMsg" text="" GridPane.rowIndex="3" GridPane.columnIndex="0" GridPane.columnSpan="2"
          GridPane.halignment="CENTER"/>

    <Button text="申请注册" GridPane.rowIndex="4" GridPane.columnIndex="0" visible="true" fx:id="enroll"
            GridPane.columnSpan="2" GridPane.halignment="CENTER" onAction="#enrollBtn" styleClass="enroll-btn"/>

    <Button text="修改密码" GridPane.rowIndex="4" GridPane.columnIndex="0" visible="false" fx:id="alert"
            GridPane.columnSpan="2" GridPane.halignment="CENTER" onAction="#alertBtn" styleClass="enroll-btn"/>

    <stylesheets>
        <URL value="@login.css"/>
    </stylesheets>

</GridPane>

login.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>

<?import javafx.scene.control.Button?>


<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.text.Text?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.PasswordField?>
<?import java.net.URL?>
<?import javafx.scene.layout.HBox?>
<GridPane fx:controller="com.hk.sky.bookmanager.controller.LoginController"
          xmlns:fx="http://javafx.com/fxml" vgap="8" hgap="8" styleClass="login" >

    <padding>
        <Insets top="40" left="30"/>
    </padding>

    <Text id="login-title" text="登 录" GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2"
          GridPane.halignment="CENTER"/>

    <Label text="用户名:" GridPane.rowIndex="1" GridPane.columnIndex="0"/>
    <TextField fx:id="username" GridPane.rowIndex="1" GridPane.columnIndex="1"/>

    <Label text="密码:" GridPane.rowIndex="2" GridPane.columnIndex="0"/>
    <PasswordField fx:id="password" GridPane.rowIndex="2" GridPane.columnIndex="1"/>

    <Text fx:id="errorMsg" GridPane.rowIndex="3" GridPane.columnIndex="1"/>

    <Button text="登录" GridPane.rowIndex="4" GridPane.columnIndex="0" GridPane.halignment="RIGHT"
            onAction="#checkLogin" styleClass="login-btn" >
    </Button>

    <Button text="注册" GridPane.rowIndex="4" GridPane.columnIndex="1" GridPane.halignment="RIGHT"
            onAction="#enrollLogin" styleClass="login-btn"/>


    <stylesheets>
        <URL value="@login.css"/>
    </stylesheets>

</GridPane>

5、效果展示(对应功能实现在相应代码中)

1)、登录功能

 

 

 2)、注册功能

 

 

 

 3)、后台主页面

 4)、修改密码页

 

 5)注销页

 点击确定,则会弹出下面信息,则该账号无法再次使用,需要重新注册,或者使用其他账号。接下来则会显示出 空白账号密码 的登陆页面

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/116660.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嘘!P站数据分析年报;各省市疫情感染进度条;爱奇艺推出元宇宙App;You推出AI聊天机器人;GitHub今日热榜 | ShowMeAI资讯日报

&#x1f440;日报合辑 | &#x1f3a1;AI应用与工具大全 | &#x1f514;公众号资料下载 | &#x1f369;韩信子 &#x1f4e2; 『The 2022 Year in Review』P站2022年度报告 Pornhub 发布了第 9 次年度报告&#xff0c;数据科学家们绘制了多张彩色可视化图表&#xff0c;回顾…

Spring注册Bean系列--方法3:@Import+@Bean

原文网址&#xff1a;Spring注册Bean系列--方法3&#xff1a;ImportBean_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Spring注册Bean的方法&#xff1a;ImportBean。 注册Bean的方法我写了一个系列&#xff0c;见&#xff1a;Spring注册Bean(提供Bean)系列--方法大全_IT利刃出鞘…

Redis-SDS

本文你能得到&#xff1a; 1 SDS基本介绍 。 2 SDS与 C语言传统字符串的区别&#xff0c;为什么使用SDS。 3 SDS的结构和策略详解。 1 SDS 是什么&#xff1f;用来做什么&#xff1f; 1.1 ​ Redis没有直接使用C语言传统的字符串表示&#xff08;以空字符结尾的字符数组&a…

[网络工程师]-STP

生成树协议&#xff08;Spanning Tree Protocol&#xff0c;STP&#xff09;是一种链路管理协议&#xff0c;为网络提供路径冗余&#xff0c;同时防止产生环路。交换机之间使用网桥协议数据单元&#xff08;Bridge Protocol Data Unit&#xff0c;BPDU&#xff09;来交换STP信息…

C语言中单井号(#)和双井号(##)在宏语句中的应用

在阅读Linux内核代码过程中&#xff0c;特别是一些预处理指令宏的时候&#xff0c;会看到宏语句里会包含一些# 或者是连着的## 符号&#xff0c;刚接触的时候觉得很一头雾水&#xff0c;但这些宏语句有时候绕不开&#xff0c;所以为了更好地读懂这些代码&#xff0c;很有必要仔…

头豹研究院发布《2022年腾讯安全威胁情报能力中心分析报告》:助力企业掌握安全防御主动权

12月23日&#xff0c;头豹研究院发布了《2022年腾讯安全威胁情报能力中心分析报告》&#xff08;以下简称《报告》&#xff09;&#xff0c;深度研究了腾讯安全威胁情报能力建设、威胁情报能力应用、威胁情报价值实践方面的现状及成果&#xff0c;从专业视角分析腾讯安全威胁情…

全网首发!华为云UCS正式商用

日前&#xff0c;华为云UCS正式商用。华为云UCS是业界首个分布式云原生服务&#xff0c;支持对华为云集群、伙伴云集群、多云集群、本地集群和附着集群的统一管理&#xff0c;覆盖中心Region、专有Region、边缘云、客户数据中心和第三方云场景&#xff0c;提供无处不在的云原生…

深度学习02:损失函数总结

目录 nn.L1Loss: nn.NLLLoss: nn.MSELoss: nn.CrossEntropyLoss: 损失函数是用来估量模型的预测值与真实值的不一致程度&#xff0c;它是一个非负实值函数。我们训练模型的过程&#xff0c;就是通过不断的迭代计算&#xff0c;使用梯度下降的优化算法&#xff0c;使得损失函…

Day 05- Vue3 Vue2响应式原理

Vue2的响应式 核心&#xff1a;通过 Object.defineProtytype() 对对象的已有属性值的读取和修改进行劫持&#xff1b; 数据劫持 --> 给对象扩展属性 --> 属性设置 实现原理&#xff1a; 对象类型&#xff1a;通过Object.defineProperty()对属性的读取、修改进行拦截…

风控黑名单库的使用与判断指南

反欺诈策略中有一类策略是专门针对黑名单用户的&#xff0c;我们称之为黑名单命中策略。 一、黑名单定义 黑名单是对严重逾期、骗贷、失联、诈骗等系列高风险客群构建的名单&#xff0c;即为明确非意向客群的名单。黑名单也是反欺诈的第一道防线&#xff0c;可以有效识别黑产客…

近些年大火的零信任,落地情况怎么样?

疫情以来      居家办公、远程工作需求激增      企业IT环境变得更加复杂      在此背景下      以“持续验证,永不信任”为核心的      零信任火爆出圈      引得国内外企业机构纷纷布局      然而根据戴尔2022全球数据保护指数(GDPI),尽管91%的组…

使用FFmpeg+go搭建m3u8点播服务器

一. 前言 HLS&#xff08;HTTP Live Streaming&#xff09; 是苹果公司提出的基于 HTTP 的流媒体传输协议&#xff0c;它的工作原理是将整个文件切分成一个个小的文件&#xff08;通常是 TS 格式文件&#xff09;&#xff0c;客户端通过 HTTP 下载播放。在准备播放某个 m3u8 媒…

Linux系统运行时参数命令--Linux基础命令和工具

目录 1 Linux基础命令和工具 1.1 grep搜索字符 1.2 find查找文件 1.3 ls显示文件 1.4 wc命令 1.5 ulimit用户资源 1.6 scp远程拷贝 1.7 dos2unix和unix2dos 1.8 sed 行处理 简单模式 替换模式 1.9 awk 列处理 C/CLinux服务器开发/后台架构师【零声教育】-学习视频…

车载软件架构—CP和AP相同与不同

文章目录 前言一、两者不同之处二、两者架构设计原则总结前言 AUTOSAR(AUTmotive Open System ARchitecture) 是汽车电子E/E系统发展的一个重要的节点。该标准是由包括BMW、DAIMLER、GM、TOYOTA、福特等主机厂和包括博世、大陆等供应商牵头成立的一个标准发展组织定义的一个开…

45页智慧交通数字化解决方案2022

【版权声明】本资料来源网络&#xff0c;仅用于行业知识分享&#xff0c;供个人学习参考&#xff0c;请勿商用。【侵删致歉】如有侵权请联系小编&#xff0c;将在收到信息后第一时间进行删除&#xff01; 完整资料领取见文末&#xff0c;部分资料内容&#xff1a; 项目建设目标…

RabbitMQ简单模式

&#x1f341;博客主页&#xff1a;&#x1f449;不会压弯的小飞侠 ✨欢迎关注&#xff1a;&#x1f449;点赞&#x1f44d;收藏⭐留言✒ ✨系列专栏&#xff1a;&#x1f449;Linux专栏 &#x1f525;欢迎大佬指正&#xff0c;一起学习&#xff01;一起加油&#xff01; 目录&…

20 个常用的 pandas 使用技巧

大家好&#xff0c;我是小寒。 今天来分享 20 个常用的 pandas 使用技巧。如果觉得不错&#xff0c;点赞、转发安排起来。 1、以 Markdown 格式输出 DataFrame import pandas as pddf pd.DataFrame({a: [1, 2, 3, 4],b: [5, 6, 7, 8]})# You can control the printing of th…

ATAC-seq分析:教程简介(1)

简介 本课程[1]介绍 Bioconductor 中的 ATACseq 分析。 该课程由 2 个部分组成。这将引导您完成正常 ATACseq 分析工作流程的每个步骤。它涵盖比对、QC、peak calling、基因组富集测试、基序富集和差异可及性测试。 环境准备 IGV IGV 可以从 BROAD 网站安装。 》 https://www.b…

mysql实现行转列作为临时表、以及字符分割行转列

1.需求&#xff1a;实现两个日期段转换为具体的日期天数&#xff08;2022-10-23至2022-10-26得到一张2022-10-23、2022-10-24、2022-10-25、2022-10-26的临时表&#xff09; SELECTDATE_FORMAT( DATE_ADD( 2022-10-23 22:00:00, INTERVAL ( help_topic_id ) DAY ), %Y-%m-%d …

微服务洞察,让微服务更透明

作者&#xff1a; 屿山 微服务作为云原生时代下一种开发软件的架构和组织方法&#xff0c;通过将明确定义的功能分成更小的服务&#xff0c;并让每个服务独立迭代&#xff0c;增加了应用程序的灵活性&#xff0c;允许开发者根据需要更轻松地更改部分应用程序。同时每个微服务可…