Java实战之管家婆记账系统(5)——主界面及功能实现

本节概要

本节将实现主界面,即在登录成功后显示的主界面,将显示用户的收入支出余额信息及在右边的面板中以表格的形式显示所有的收入支出记录。

前期准备

由于需要使用表格显示记录数据,所以需要使用到实体类来封装数据,但是JavaFX的实体类封装对象同普通的有些不一样,所以在bean包创建TableData.java类,其内容如下:

package AccountSystem.bean;
​
import javafx.beans.property.SimpleStringProperty;
​
public class TableData {
    private final SimpleStringProperty id;
    private final SimpleStringProperty type;
    private final SimpleStringProperty money;
    private final SimpleStringProperty classification;
    private final SimpleStringProperty memo;
​
    public String getId() {
        return id.get();
    }
​
    public SimpleStringProperty idProperty() {
        return id;
    }
​
    public void setId(String id) {
        this.id.set(id);
    }
​
    public String getType() {
        return type.get();
    }
​
    public SimpleStringProperty typeProperty() {
        return type;
    }
​
    public void setType(String type) {
        this.type.set(type);
    }
​
    public String getMoney() {
        return money.get();
    }
​
    public SimpleStringProperty moneyProperty() {
        return money;
    }
​
    public void setMoney(String money) {
        this.money.set(money);
    }
​
    public String getClassification() {
        return classification.get();
    }
​
    public SimpleStringProperty classificationProperty() {
        return classification;
    }
​
    public void setClassification(String classification) {
        this.classification.set(classification);
    }
​
    public String getMemo() {
        return memo.get();
    }
​
    public SimpleStringProperty memoProperty() {
        return memo;
    }
​
    public void setMemo(String memo) {
        this.memo.set(memo);
    }
​
    public String getDate() {
        return date.get();
    }
​
    public SimpleStringProperty dateProperty() {
        return date;
    }
​
    public void setDate(String date) {
        this.date.set(date);
    }
​
    private final SimpleStringProperty date;
​
    public TableData(String id, String type, String money, String classification, String memo, String date) {
        this.id = new SimpleStringProperty(id);
        this.type = new SimpleStringProperty(type);
        this.money = new SimpleStringProperty(money);
        this.classification = new SimpleStringProperty(classification);
        this.memo = new SimpleStringProperty(memo);
        this.date = new SimpleStringProperty(date);
    }
​
}

并且由于会对账目记录进行查询,所以又在dao包下创建RecordDao.java类,里面是对records表的增删改查方法(所以后期调用方法将不再解释),代码如下:

package AccountSystem.dao;
​
import AccountSystem.bean.Record;
​
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
​
public class RecordDao {
​
    /**
     * 添加账目记录
     *
     * @param record 账目记录
     * @return 如果添加成功则返回true,否则返回false
     */
    public boolean addRecord(Record record) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        int num = 0;
        try {
            // 获得数据的连接
            conn = JDBCUtils.getConnection();
            // 获得Statement对象
            stmt = conn.createStatement();
            // 拼接SQL语句
            String sql = "insert into tb_records (uId,rType,rMoney,rClassification,rMemo,rDate) values(" +
                    record.getUserId() + ",'" +
                    record.getRecordType() + "'," +
                    record.getRecordMoney() + ",'" +
                    record.getRecordClassification() + "','" +
                    record.getRecordMemo() + "','" +
                    record.getRecordDate() + "');";
            // 执行插入语句,返回受影响行数
            num = stmt.executeUpdate(sql);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.release(rs, stmt, conn);
        }
        return num > 0;
    }
​
    /**
     * 查询指定用户的所有账目记录
     *
     * @param userId 指定的用户id
     * @return 返回查询结果集
     */
    public List<Record> selectByUserId(int userId) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        List<Record> recordList = new ArrayList<>();
        try {
            //获得数据的连接
            conn = JDBCUtils.getConnection();
            //获得Statement对象
            stmt = conn.createStatement();
            // 拼装SQL语句
            String sql = "select * from tb_records where uId=" + userId;
            //发送SQL语句
            rs = stmt.executeQuery(sql);
            // 循环添加数据
            while (rs.next()) {
                Record record = new Record();
                record.setRecordId(rs.getInt(1));
                record.setUserId(rs.getInt(2));
                record.setRecordType(rs.getString(3));
                record.setRecordMoney(rs.getFloat(4));
                record.setRecordClassification(rs.getString(5));
                record.setRecordMemo(rs.getString(6));
                record.setRecordDate(rs.getString(7));
                recordList.add(record);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.release(rs, stmt, conn);
        }
        return recordList;
    }
​
    /**
     * 查询账目记录通过账目记录id和用户id
     *
     * @param recordId 账目记录id
     * @param userId   用户id
     * @return 返回查询到的账目记录
     */
    public Record selectRecordByIdAndUserId(int recordId, int userId) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        Record record = new Record();
        try {
            //获得数据的连接
            conn = JDBCUtils.getConnection();
            //获得Statement对象
            stmt = conn.createStatement();
            //发送SQL语句
            String sql = "select * from tb_records where rId=" + recordId + " and uId=" + userId + ";";
            // 执行查询
            rs = stmt.executeQuery(sql);
            // 循环结果
            while (rs.next()) {
                record.setRecordId(rs.getInt(1));
                record.setUserId(rs.getInt(2));
                record.setRecordType(rs.getString(3));
                record.setRecordMoney(rs.getFloat(4));
                record.setRecordClassification(rs.getString(5));
                record.setRecordMemo(rs.getString(6));
                record.setRecordDate(rs.getString(7));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.release(rs, stmt, conn);
        }
        return record;
    }
​
    /**
     * 删除账目记录
     *
     * @param record 账目记录
     * @return 如果删除成功则返回true,否则返回false
     */
    public boolean deleteRecord(Record record) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        int num = 0;
        try {
            //获得数据的连接
            conn = JDBCUtils.getConnection();
            //获得Statement对象
            stmt = conn.createStatement();
            //发送SQL语句
            String sql = "delete from tb_records where rId=" + record.getRecordId() + ";";
            // 返回受影响行数
            num = stmt.executeUpdate(sql);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.release(rs, stmt, conn);
        }
        return num > 0;
    }
​
    /**
     * 更新账目记录
     *
     * @param record 账目记录
     * @return 如果更新成功则返回true,否则返回false
     */
    public boolean updateRecord(Record record) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        int num = 0;
        try {
            //获得数据的连接
            conn = JDBCUtils.getConnection();
            //获得Statement对象
            stmt = conn.createStatement();
            //发送SQL语句
            String sql = "update tb_records set rType='" + record.getRecordType() + "',rMoney=" + record.getRecordMoney() + ",rClassification='" + record.getRecordClassification() + "',rMemo='" + record.getRecordMemo() + "',rDate='" + record.getRecordDate() + "' where rId=" + record.getRecordId() + ";";
            // 执行更新,返回受影响行数
            num = stmt.executeUpdate(sql);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.release(rs, stmt, conn);
        }
        return num > 0;
    }
​
    /**
     * 获取指定用户支出或收入的总额
     *
     * @param recordType 记录类型,支出或收入
     * @param userId     用户id
     * @return 返回用户支出或收入的总额
     */
    public float getTotalAccount(String recordType, int userId) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        float total = 0f;
        try {
            //获得数据的连接
            conn = JDBCUtils.getConnection();
            //获得Statement对象
            stmt = conn.createStatement();
            // 拼接SQL语句
            String sql = "select SUM(rMoney) from tb_records where rType='" + recordType + "' and uId=" + userId + ";";
            // 发送SQL语句
            rs = stmt.executeQuery(sql);
            while (rs.next()) {
                total = rs.getFloat(1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.release(rs, stmt, conn);
        }
        return total;
    }
​
    /**
     * 根据SQL条件语句获取唯一结果值
     *
     * @param sql SQL语句
     * @return 返回结果
     */
    public float getResultValueBySql(String sql) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        float resultValue = 0f;
        try {
            //获得数据的连接
            conn = JDBCUtils.getConnection();
            //获得Statement对象
            stmt = conn.createStatement();
            //发送SQL语句
            rs = stmt.executeQuery(sql);
            while (rs.next()) {
                resultValue = rs.getFloat(1);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.release(rs, stmt, conn);
        }
        return resultValue;
    }
​
    /**
     * 根据SQL条件语句获取账目记录
     *
     * @param sql SQL语句
     * @return 返回查询结果集
     */
    public List<Record> getRecordBySql(String sql) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        List<Record> recordList = new ArrayList<Record>();
        try {
            //获得数据的连接
            conn = JDBCUtils.getConnection();
            //获得Statement对象
            stmt = conn.createStatement();
            //发送SQL语句
            rs = stmt.executeQuery(sql);
            while (rs.next()) {
                Record record = new Record();
                record.setRecordId(rs.getInt(1));
                record.setUserId(rs.getInt(2));
                record.setRecordType(rs.getString(3));
                record.setRecordMoney(rs.getFloat(4));
                record.setRecordClassification(rs.getString(5));
                record.setRecordMemo(rs.getString(6));
                record.setRecordDate(rs.getString(7));
                recordList.add(record);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.release(rs, stmt, conn);
        }
        return recordList;
    }
​
    /**
     * 操作结果:在删除数据后,刷新主键编号
     */
    public void refreshPrimaryKey() {
        String refreshSQL1 = "alter table tb_records drop rId;";
        String refreshSQL2 = "alter table tb_records add rId int not null FIRST;";
        String refreshSQL3 = "alter table tb_records modify column rId int not null AUTO_INCREMENT,add primary key" +
                "(rId);";
        Connection conn = null;
        Statement stmt = null;
        try {
            conn = JDBCUtils.getConnection();
            //获得Statement对象
            stmt = conn.createStatement();
            stmt.executeUpdate(refreshSQL1);
            stmt.executeUpdate(refreshSQL2);
            stmt.executeUpdate(refreshSQL3);
        } catch (SQLException | IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.release(stmt, conn);
        }
​
    }
​
}

需要对主界面的表格控件进行数据填充,所以在tools包创建PublicTools.java类,里面是填充数据到表格中的方法,写好之后直接进行调用即可,代码如下:

package AccountSystem.tools;
​
import AccountSystem.bean.Record;
import AccountSystem.bean.TableData;
import AccountSystem.dao.RecordDao;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
​
import java.util.List;
​
public class PublicTools {
​
    /**
     * 操作结果:向下拉列表框中添加列表项
     *
     * @param comboBox 下拉列表框
     * @param items    列表项
     */
    public void public_addComboBoxItems(ComboBox comboBox, Object[] items) {
        // 清除下列列表框中的所有选项
        comboBox.getItems().clear();
        ObservableList options = FXCollections.observableArrayList(items);
        // 添加下拉列表项
        comboBox.setItems(options);
    }
​
​
    /**
     * 操作结果:通过SQL语句从数据库得到表格视图的数据
     *
     * @param sql SQL语句
     * @return ObservableList
     */
    public ObservableList<TableData> public_getTableViewData(String sql) {
        // 实例化RecordDao对象
        RecordDao recordDao = new RecordDao();
        // 通过SQL语句从数据库查询账目记录信息
        List<Record> recordList = recordDao.getRecordBySql(sql);
        // 创建ObservableList<TableData>
        ObservableList<TableData> data = FXCollections.observableArrayList();
        // 循环遍历
        for (Record r : recordList) {
            // 封装数据到TableData实体类种
            TableData td = new TableData(String.valueOf(r.getRecordId()), r.getRecordType(),
                    String.valueOf(r.getRecordMoney()), r.getRecordClassification(), r.getRecordMemo(),
                    r.getRecordDate());
            // 将封装完成的实体类对象添加到集合种
            data.add(td);
        }
        // 返回添加数据完成的集合
        return data;
    }
​
    /**
     * 操作结果:设置表格视图的数据
     *
     * @param tableView            表格视图
     * @param data                 数据
     * @param idColumn             编号列
     * @param typeColumn           类型列
     * @param moneyColumn          金额列
     * @param classificationColumn 分类列
     * @param memoColumn           备注列
     * @param dateColumn           日期列
     */
    public void public_initTableViewData(TableView tableView,
                                         ObservableList<TableData> data,
                                         TableColumn<TableData, String> idColumn,
                                         TableColumn<TableData, String> typeColumn,
                                         TableColumn<TableData, String> moneyColumn,
                                         TableColumn<TableData, String> classificationColumn,
                                         TableColumn<TableData, String> memoColumn,
                                         TableColumn<TableData, String> dateColumn) {
        // 设置各列的数据
        idColumn.setCellValueFactory(cellData -> cellData.getValue().idProperty());
        typeColumn.setCellValueFactory(cellData -> cellData.getValue().typeProperty());
        moneyColumn.setCellValueFactory(cellData -> cellData.getValue().moneyProperty());
        classificationColumn.setCellValueFactory(cellData -> cellData.getValue().classificationProperty());
        memoColumn.setCellValueFactory(cellData -> cellData.getValue().memoProperty());
        dateColumn.setCellValueFactory(cellData -> cellData.getValue().dateProperty());
        tableView.setItems(data);
    }
}

 

实现主界面

第一步:先设计界面,在view包下创建mainPage.fxml文件,并使用Scene Builder进行界面设计,各个控件的属性配置和事件设定参照下面的代码。

<?xml version="1.0" encoding="UTF-8"?>
​
<?import javafx.scene.control.*?>
<?import javafx.scene.Cursor?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.input.KeyCodeCombination?>
<?import javafx.scene.layout.*?>
<AnchorPane prefHeight="600.0" prefWidth="900.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
            fx:controller="AccountSystem.controller.MainPageController">
    <children>
        <SplitPane dividerPositions="0.29797979797979796" prefHeight="600.0" prefWidth="900.0">
            <items>
                <AnchorPane fx:id="leftSplitPane" minHeight="0.0" minWidth="0.0" prefHeight="398.0" prefWidth="239.0">
                    <children>
                        <VBox alignment="CENTER" layoutX="-1.0" prefHeight="598.0" prefWidth="264.0">
                            <children>
                                <HBox alignment="CENTER" prefHeight="150.0" prefWidth="157.0">
                                    <children>
                                        <ImageView fx:id="userImage" fitHeight="150.0" fitWidth="254.0"
                                                   nodeOrientation="RIGHT_TO_LEFT" pickOnBounds="true"
                                                   preserveRatio="true">
                                            <cursor>
                                                <Cursor fx:constant="HAND"/>
                                            </cursor>
                                            <image>
                                                <Image url="@../images/panda.png"/>
                                            </image>
                                        </ImageView>
                                    </children>
                                </HBox>
                                <HBox alignment="CENTER" prefHeight="56.0" prefWidth="174.0">
                                    <children>
                                        <Label fx:id="userNameLabel" text="用户名"/>
                                    </children>
                                </HBox>
                                <HBox alignment="CENTER" prefHeight="50.0" prefWidth="174.0">
                                    <children>
                                        <Separator prefWidth="200.0"/>
                                    </children>
                                </HBox>
                                <HBox alignment="CENTER" prefHeight="60.0" prefWidth="200.0">
                                    <children>
                                        <Label fx:id="totalOutputLabel" text="总支出:"/>
                                        <TextField fx:id="totalOutputTextField" editable="false" prefHeight="30.0"
                                                   prefWidth="110.0"/>
                                    </children>
                                </HBox>
                                <HBox alignment="CENTER" prefHeight="60.0" prefWidth="200.0">
                                    <children>
                                        <Label fx:id="totalInputLabel" text="总收入:"/>
                                        <TextField fx:id="totalInputTextField" editable="false" prefHeight="30.0"
                                                   prefWidth="110.0"/>
                                    </children>
                                </HBox>
                                <HBox alignment="CENTER" prefHeight="60.0" prefWidth="200.0">
                                    <children>
                                        <Label fx:id="balanceLabel" text="余   额:"/>
                                        <TextField fx:id="balanceTextField" editable="false" prefHeight="30.0"
                                                   prefWidth="110.0"/>
                                    </children>
                                </HBox>
                            </children>
                        </VBox>
                    </children>
                </AnchorPane>
                <AnchorPane fx:id="rightSplitPane" minHeight="0.0" minWidth="0.0" prefHeight="398.0" prefWidth="354.0">
                    <children>
                        <MenuBar prefHeight="32.0" prefWidth="626.0">
                            <menus>
                                <Menu mnemonicParsing="false" text="文件">
                                    <items>
                                        <MenuItem fx:id="importMenuItem" mnemonicParsing="false"
                                                  onAction="#importMenuItemEvent" text="导入"/>
                                        <MenuItem fx:id="exportMenuItem" mnemonicParsing="false"
                                                  onAction="#exportMenuItemEvent" text="导出"/>
                                        <MenuItem fx:id="backupMenuItem" mnemonicParsing="false"
                                                  onAction="#backupMenuItemEvent" text="备份"/>
                                        <MenuItem fx:id="recoverMenuItem" mnemonicParsing="false"
                                                  onAction="#recoverMenuItemEvent" text="恢复"/>
                                        <MenuItem fx:id="exitMenuItem" mnemonicParsing="false"
                                                  onAction="#exitMenuItemEvent" text="退出">
                                            <accelerator>
                                                <KeyCodeCombination alt="DOWN" code="F4" control="UP" meta="UP"
                                                                    shift="UP" shortcut="UP"/>
                                            </accelerator>
                                        </MenuItem>
                                    </items>
                                </Menu>
                                <Menu mnemonicParsing="false" text="编辑">
                                    <items>
                                        <MenuItem fx:id="addMenuItem" mnemonicParsing="false"
                                                  onAction="#addMenuItemEvent" text="添加">
                                            <accelerator>
                                                <KeyCodeCombination alt="UP" code="A" control="UP" meta="UP"
                                                                    shift="DOWN" shortcut="UP"/>
                                            </accelerator>
                                        </MenuItem>
                                        <MenuItem fx:id="deleteMenuItem" mnemonicParsing="false"
                                                  onAction="#deleteMenuItemEvent" text="删除">
                                            <accelerator>
                                                <KeyCodeCombination alt="UP" code="D" control="UP" meta="UP"
                                                                    shift="DOWN" shortcut="UP"/>
                                            </accelerator>
                                        </MenuItem>
                                        <MenuItem fx:id="alterMenuItem" mnemonicParsing="false"
                                                  onAction="#alterMenuItemEvent" text="修改"/>
                                    </items>
                                </Menu>
                                <Menu mnemonicParsing="false" text="查询">
                                    <items>
                                        <MenuItem fx:id="checkMenuItem" mnemonicParsing="false"
                                                  onAction="#checkMenuItemEvent" text="查询"/>
                                        <Menu mnemonicParsing="false" text="条件查询">
                                            <items>
                                                <MenuItem fx:id="dateCheckMenuItem" mnemonicParsing="false"
                                                          onAction="#dateCheckMenuItemEvent" text="按日期查询"/>
                                                <MenuItem fx:id="classificationCheckMenuItem" mnemonicParsing="false"
                                                          onAction="#classificationCheckMenuItemEvent" text="按分类查询"/>
                                                <MenuItem fx:id="memoCheckMenuItem" mnemonicParsing="false"
                                                          onAction="#memoCheckMenuItemEvent" text="按备注查询"/>
                                            </items>
                                        </Menu>
                                        <Menu mnemonicParsing="false" text="图表">
                                            <items>
                                                <MenuItem fx:id="barChartMenuItem" mnemonicParsing="false"
                                                          onAction="#barChartMenuItemEvent" text="条形图"/>
                                                <MenuItem fx:id="lineChartMenuItem" mnemonicParsing="false"
                                                          onAction="#lineChartMenuItemEvent" text="折线图"/>
                                                <MenuItem fx:id="pieChartMenuItem" mnemonicParsing="false"
                                                          onAction="#pieChartMenuItemEvent" text="饼图"/>
                                            </items>
                                        </Menu>
                                        <MenuItem fx:id="reportMenuItem" mnemonicParsing="false"
                                                  onAction="#reportMenuItemEvent" text="报告"/>
                                    </items>
                                </Menu>
                                <Menu mnemonicParsing="false" text="选项">
                                    <items>
                                        <MenuItem fx:id="addClassificationMenuItem" mnemonicParsing="false"
                                                  onAction="#addClassificationMenuItemEvent" text="添加分类"/>
                                        <MenuItem fx:id="userInfoMenuItem" mnemonicParsing="false"
                                                  onAction="#userInfoMenuItemEvent" text="用户信息"/>
                                        <Menu mnemonicParsing="false" text="主题">
                                            <items>
                                                <RadioMenuItem fx:id="defaultRadioMenuItem" mnemonicParsing="false"
                                                               onAction="#defaultRadioMenuItemEvent" text="默认">
                                                    <toggleGroup>
                                                        <ToggleGroup fx:id="radioMenuItem"/>
                                                    </toggleGroup>
                                                </RadioMenuItem>
                                                <RadioMenuItem fx:id="blackRadioMenuItem" mnemonicParsing="false"
                                                               onAction="#blackRadioMenuItemEvent" text="经典黑"
                                                               toggleGroup="$radioMenuItem"/>
                                                <RadioMenuItem fx:id="whiteRadioMenuItem" mnemonicParsing="false"
                                                               onAction="#whiteRadioMenuItemEvent" text="优雅白"
                                                               toggleGroup="$radioMenuItem"/>
                                            </items>
                                        </Menu>
                                    </items>
                                </Menu>
                                <Menu mnemonicParsing="false" text="帮助">
                                    <items>
                                        <MenuItem fx:id="abutSoftMenuItem" mnemonicParsing="false"
                                                  onAction="#abutSoftMenuItemEvent" text="关于软件"/>
                                        <MenuItem fx:id="helpMenuItem" mnemonicParsing="false"
                                                  onAction="#helpMenuItemEvent" text="帮助">
                                            <accelerator>
                                                <KeyCodeCombination alt="UP" code="H" control="DOWN" meta="UP"
                                                                    shift="UP" shortcut="UP"/>
                                            </accelerator>
                                        </MenuItem>
                                    </items>
                                </Menu>
                            </menus>
                        </MenuBar>
                        <TableView fx:id="tableView" editable="true" layoutY="43.0" prefHeight="557.0" prefWidth="626.0"
                                   tableMenuButtonVisible="true">
                            <columns>
                                <TableColumn fx:id="idColumn" prefWidth="76.0" text="序号"/>
                                <TableColumn fx:id="typeColumn" prefWidth="78.0" text="类型"/>
                                <TableColumn fx:id="moneyColumn" prefWidth="79.0" text="金额"/>
                                <TableColumn fx:id="classificationColumn" prefWidth="86.0" text="分类"/>
                                <TableColumn fx:id="memoColumn" prefWidth="120.0" text="备注"/>
                                <TableColumn fx:id="dateColumn" prefWidth="173.0" text="日期"/>
                            </columns>
                            <contextMenu>
                                <ContextMenu>
                                    <items>
                                        <MenuItem fx:id="refreshContextMenu" mnemonicParsing="false"
                                                  onAction="#refreshContextMenuEvent" text="刷新"/>
                                        <MenuItem fx:id="deleteContextMenu" mnemonicParsing="false"
                                                  onAction="#deleteContextMenuEvent" text="删除"/>
                                        <MenuItem fx:id="addContextMenu" mnemonicParsing="false"
                                                  onAction="#addContextMenuEvent" text="添加"/>
                                        <MenuItem fx:id="alterContextMenu" mnemonicParsing="false"
                                                  onAction="#alterContextMenuEvent" text="修改"/>
                                    </items>
                                </ContextMenu>
                            </contextMenu>
                        </TableView>
                        <Separator layoutX="-1.0" layoutY="32.0" prefHeight="12.0" prefWidth="626.0"/>
                    </children>
                </AnchorPane>
            </items>
        </SplitPane>
    </children>
</AnchorPane>

第二步:创建好FXML界面好就是创建控制器类,在controller包下创建MainPageController.java类,并在Scene Builder中复制控制器类的基本代码。

package AccountSystem.controller;
​
import AccountSystem.MainApp;
import AccountSystem.bean.Session;
import AccountSystem.bean.TableData;
import AccountSystem.bean.User;
import AccountSystem.dao.RecordDao;
import AccountSystem.tools.DateTools;
import AccountSystem.tools.PublicTools;
import AccountSystem.tools.SimpleTools;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
​
/**
 * 主界面控制器
 *
 * @author lck100
 */
public class MainPageController {
​
    private SimpleTools simpleTools = new SimpleTools();
    private RecordDao recordDao = new RecordDao();
    private MainApp mainApp = new MainApp();
    private PublicTools publicTools = new PublicTools();
    private DateTools dateTools = new DateTools();
​
    @FXML
    public RadioMenuItem defaultRadioMenuItem;
​
    @FXML
    public RadioMenuItem blackRadioMenuItem;
​
    @FXML
    public RadioMenuItem whiteRadioMenuItem;
​
    @FXML
    private MenuItem refreshContextMenu;
​
    @FXML
    private TableColumn<TableData, String> classificationColumn;
​
    @FXML
    private TextField totalOutputTextField;
​
    @FXML
    private TextField totalInputTextField;
​
    @FXML
    private ImageView userImage;
​
    @FXML
    private Label userNameLabel;
​
    @FXML
    private TableColumn<TableData, String> moneyColumn;
​
    public TableView<TableData> getTableView() {
        return tableView;
    }
​
    public void setTableView(TableView<TableData> tableView) {
        this.tableView = tableView;
    }
​
    @FXML
    private TableView<TableData> tableView;
​
    @FXML
    private TableColumn<TableData, String> typeColumn;
​
    @FXML
    private TableColumn<TableData, String> memoColumn;
​
    @FXML
    private TextField balanceTextField;
​
    @FXML
    private TableColumn<TableData, String> dateColumn;
​
    @FXML
    private TableColumn<TableData, String> idColumn;
​
    /**
     * “导入”菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void importMenuItemEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * “导出”菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void exportMenuItemEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * “备份”菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void backupMenuItemEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * “恢复”菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void recoverMenuItemEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * “退出”菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void exitMenuItemEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * ”添加“菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void addMenuItemEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * ”删除“菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void deleteMenuItemEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * ”修改“菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void alterMenuItemEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * “删除”右键菜单的事件监听器
     *
     * @param event 事件
     */
    @FXML
    public void deleteContextMenuEvent(ActionEvent event) {
​
    }
​
    /**
     * “添加”右键菜单的事件监听器
     *
     * @param event 事件
     */
    @FXML
    public void addContextMenuEvent(ActionEvent event) {
​
    }
​
    /**
     * “修改”右键菜单的事件监听器
     *
     * @param event 事件
     */
    @FXML
    public void alterContextMenuEvent(ActionEvent event) {
​
    }
​
    /**
     * ”刷新“右键菜单的事件监听器
     *
     * @param actionEvent 事件
     */
    public void refreshContextMenuEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * ”查询“菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void checkMenuItemEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * ”条形图“菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void barChartMenuItemEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * “折线图”菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void lineChartMenuItemEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * ”饼图“菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void pieChartMenuItemEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * ”添加分类“菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void addClassificationMenuItemEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * “用户信息”菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void userInfoMenuItemEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * “报告”菜单项的事件监听器
     *
     * @param event 事件
     */
    @FXML
    public void reportMenuItemEvent(ActionEvent event) {
​
    }
​
    /**
     * “关于软件”菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void abutSoftMenuItemEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * “帮助”菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void helpMenuItemEvent(ActionEvent actionEvent) {
​
    }
​
    /**
     * ”按日期查询“菜单项的事件监听器
     *
     * @param event 事件
     */
    @FXML
    public void dateCheckMenuItemEvent(ActionEvent event) {
​
    }
​
    /**
     * ”按分类查询“菜单项的事件监听器
     *
     * @param event 事件
     */
    @FXML
    public void classificationCheckMenuItemEvent(ActionEvent event) {
​
    }
​
    /**
     * ”按备注查询“菜单项的事件监听器
     *
     * @param event 事件
     */
    @FXML
    public void memoCheckMenuItemEvent(ActionEvent event) {
​
    }
​
    /**
     * “默认”菜单项的事件监听器方法
     *
     * @param event 事件
     */
    public void defaultRadioMenuItemEvent(ActionEvent event) {
​
    }
​
    /**
     * “经典黑”菜单项的事件监听器方法
     *
     * @param event 事件
     */
    public void blackRadioMenuItemEvent(ActionEvent event) {
​
    }
​
    /**
     * “优雅白”菜单项的事件监听器方法
     *
     * @param event 事件
     */
    public void whiteRadioMenuItemEvent(ActionEvent event) {
​
    }
}

第三步:接着是加载FXML文件显示出主界面。

在MainApp.java中添加如下方法:

    /**
     * 操作结果:主操作界面
     */
    public Scene initMainFrame() {
        try {
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(MainApp.class.getResource("view/mainPage.fxml"));
            AnchorPane page = (AnchorPane) loader.load();
​
            Stage mainFrameStage = new Stage();
            mainFrameStage.setTitle("管家婆系统");
            mainFrameStage.setResizable(true);
            mainFrameStage.setAlwaysOnTop(false);
            mainFrameStage.initModality(Modality.APPLICATION_MODAL);
            mainFrameStage.initOwner(primaryStage);
​
            Scene scene = new Scene(page);
            mainFrameStage.setScene(scene);
​
            mainFrameStage.showAndWait();
            return scene;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

并在LogupFrameController.java中调用该方法(在上一节中被注释的那一句),即在登录成功后打开主界面。

// 打开主窗口
new MainApp().initMainFrame();

运行程序,没有任何数据,是如下界面:

填充数据

在完成界面后,就是提供数据并将其显示出来,而主界面需要显示的信息包括该用户的图像、收入、支出、余额及所有收入支出记录。

在MainPageController.java中添加initUserRecord()方法用来显示该用户的信息:

    /**
     * 操作结果:初始化用户名、总支出、总收入及余额
     */
    private void initUserRecord() {
        // 获取登录成功的用户
        User user = Session.getUser();
        // 获取用户支出的总金额
        float totalOutput = recordDao.getTotalAccount("支出", user.getUserId());
        // 获取用户收入的总金额
        float totalInput = recordDao.getTotalAccount("收入", user.getUserId());
        // 获取余额
        float balance = totalInput - totalOutput;
        // 设置图片
        userImage.setImage(new Image("file:" + user.getUserImagePath()));
        userImage.setSmooth(true);
        userImage.setFitWidth(100);
        userImage.setFitHeight(100);
        userImage.setCache(true);
        userImage.setPreserveRatio(true);
        // 将支出金额、收入金额、余额、用户名设置到文本框种
        totalOutputTextField.setText(String.valueOf(totalOutput));
        totalInputTextField.setText(String.valueOf(totalInput));
        balanceTextField.setText(String.valueOf(balance));
        userNameLabel.setText(Session.getUser().getUserName());
    }

其中可以通过“User user = Session.getUser();”获取登录用户的信息,这是在登录成功保存在Session中的,同时通过调用RecordDao中的方法获取用户收入和支出的总金额,并计算余额,同时将信息显示在主界面上。

接着是读取所有记录并显示在表格上,所以同时添加方法:

    /**
     * 操作结果:初始化数据表视图
     */
    private void initAddDataToTableView() {
        String sql = "select * from tb_records where uId=" + Session.getUser().getUserId() + ";";
        publicTools.public_initTableViewData(tableView
                , publicTools.public_getTableViewData(sql)
                , idColumn
                , typeColumn
                , moneyColumn
                , classificationColumn
                , memoColumn
                , dateColumn);
    }

是通过sql语句获取用户的收入支出记录,并调用PublicTools中的方法将其填充到表格控件中。

写好方法后,接着就是调用执行这些方法,可以通过initialize()方法来处理,initialize()方法是JavaFX控制器类中的处理方法,用来初始化一些数据信息,所以将其添加到initialize()方法即可。

代码如下:

    /**
     * 初始化界面信息
     */
    @FXML
    public void initialize() {
        // 刷新主键编号
        new RecordDao().refreshPrimaryKey();
        // 初始化用户记录
        initUserRecord();
        // 初始化表格数据
        initAddDataToTableView();
    }

其中refreshPrimaryKey()方法在这里可以注释删除不使用,这是在删除数据后更新主键编号调用的,而在本节中没有进行记录的删除,所以该方法的调用可以删除也不会影响使用。

所有的数据调用已经实现,所以可以运行程序了,登录成功后,如果用户是有记录数据的话,界面如下:

img

可搜索微信公众号【Java实例程序】或者扫描下方二维码关注公众号获取更多。

注意:在公众号后台回复【20200317】可获取本章的源码 。

发布了500 篇原创文章 · 获赞 77 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/cnds123321/article/details/104272026