Java实战之管家婆记账系统(20)——添加分类界面及功能实现

本节概要

如果用户想要自定义分类,那么本节就是为了实现该功能,使得用户能够自定义收入和支出分类。

 

创建界面

首先在view包下创建addClassificationFrame.fxml文件,使用Scene Builder来设计界面,界面中的各个组件的属性和事件方法可以参考下面的代码:

<?xml version="1.0" encoding="UTF-8"?>
​
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<AnchorPane prefHeight="517.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
            fx:controller="AccountSystem.controller.AddClassificationFrameController">
    <children>
        <TabPane prefHeight="517.0" prefWidth="600.0" tabClosingPolicy="UNAVAILABLE">
            <tabs>
                <Tab text="支出分类">
                    <content>
                        <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
                            <children>
                                <VBox prefHeight="481.0" prefWidth="600.0" spacing="30.0">
                                    <children>
                                        <Label text="添加支出分类" textFill="#7d7d7d">
                                            <font>
                                                <Font size="20.0"/>
                                            </font>
                                        </Label>
                                        <HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0"
                                              spacing="20.0">
                                            <children>
                                                <Label text="分类名称">
                                                    <font>
                                                        <Font size="28.0"/>
                                                    </font>
                                                </Label>
                                                <TextField fx:id="outputClassificationNameTextField"
                                                           promptText="输入支出分类名称">
                                                    <font>
                                                        <Font size="26.0"/>
                                                    </font>
                                                </TextField>
                                            </children>
                                        </HBox>
                                        <HBox alignment="CENTER" prefHeight="62.0" prefWidth="600.0">
                                            <children>
                                                <Button fx:id="addOutputButton" mnemonicParsing="false"
                                                        onAction="#addOutputButtonEvent" prefHeight="42.0"
                                                        prefWidth="216.0" text="添加支出">
                                                    <font>
                                                        <Font size="21.0"/>
                                                    </font>
                                                </Button>
                                            </children>
                                        </HBox>
                                        <Label text="支出分类列表" textFill="#7d7d7d">
                                            <font>
                                                <Font size="20.0"/>
                                            </font>
                                        </Label>
                                        <ListView fx:id="outputClassificationListView"
                                                  onEditCommit="#outputClassificationListViewCommitEvent"
                                                  prefHeight="250.0" prefWidth="600.0">
                                            <contextMenu>
                                                <ContextMenu>
                                                    <items>
                                                        <MenuItem fx:id="output_editContextMenu" mnemonicParsing="false"
                                                                  onAction="#output_editContextMenuEvent" text="编辑"/>
                                                        <MenuItem fx:id="output_deleteMenuItem" mnemonicParsing="false"
                                                                  onAction="#output_deleteMenuItemEvent" text="删除"/>
                                                    </items>
                                                </ContextMenu>
                                            </contextMenu>
                                        </ListView>
                                        <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
                                            <children>
                                                <Button fx:id="outputClassificationReturnButton" mnemonicParsing="false"
                                                        onAction="#outputClassificationReturnButtonEvent" text="返回">
                                                    <font>
                                                        <Font size="21.0"/>
                                                    </font>
                                                </Button>
                                            </children>
                                        </HBox>
                                    </children>
                                </VBox>
                            </children>
                        </AnchorPane>
                    </content>
                </Tab>
                <Tab text="收入分类">
                    <content>
                        <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
                            <children>
                                <VBox prefHeight="480.0" prefWidth="600.0" spacing="30.0">
                                    <children>
                                        <Label text="添加收入分类" textFill="#7d7d7d">
                                            <font>
                                                <Font size="20.0"/>
                                            </font>
                                        </Label>
                                        <HBox alignment="CENTER_LEFT" prefHeight="100.0" prefWidth="200.0"
                                              spacing="20.0">
                                            <children>
                                                <Label text="分类名称">
                                                    <font>
                                                        <Font size="28.0"/>
                                                    </font>
                                                </Label>
                                                <TextField fx:id="inputClassificationNameTextField"
                                                           promptText="输入收入分类名称">
                                                    <font>
                                                        <Font size="26.0"/>
                                                    </font>
                                                </TextField>
                                            </children>
                                        </HBox>
                                        <HBox alignment="CENTER" prefHeight="62.0" prefWidth="600.0">
                                            <children>
                                                <Button fx:id="addInputButton" mnemonicParsing="false"
                                                        onAction="#addInputButtonEvent" prefHeight="42.0"
                                                        prefWidth="216.0" text="添加收入">
                                                    <font>
                                                        <Font size="21.0"/>
                                                    </font>
                                                </Button>
                                            </children>
                                        </HBox>
                                        <Label text="收入分类列表" textFill="#7d7d7d">
                                            <font>
                                                <Font size="20.0"/>
                                            </font>
                                        </Label>
                                        <ListView fx:id="inputClassificationListView"
                                                  onEditCommit="#inputClassificationListViewCommitEvent"
                                                  prefHeight="250.0" prefWidth="600.0">
                                            <contextMenu>
                                                <ContextMenu>
                                                    <items>
                                                        <MenuItem fx:id="input_editContextMenu" mnemonicParsing="false"
                                                                  onAction="#input_editContextMenuEvent" text="编辑"/>
                                                        <MenuItem fx:id="input_deleteContextMenu"
                                                                  mnemonicParsing="false"
                                                                  onAction="#input_deleteContextMenuEvent" text="删除"/>
                                                    </items>
                                                </ContextMenu>
                                            </contextMenu>
                                        </ListView>
                                        <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
                                            <children>
                                                <Button fx:id="inputClassificationReturnButton" mnemonicParsing="false"
                                                        onAction="#inputClassificationReturnButtonEvent" text="返回">
                                                    <font>
                                                        <Font size="21.0"/>
                                                    </font>
                                                </Button>
                                            </children>
                                        </HBox>
                                    </children>
                                </VBox>
                            </children>
                        </AnchorPane>
                    </content>
                </Tab>
            </tabs>
        </TabPane>
    </children>
</AnchorPane>

接着是在controller创建与之对应的控制器类AddClassificationFrameController.java,bong从Scene Builder中复制该界面中的组件对象和事件方法的代码到该类中:

package AccountSystem.controller;
​
import AccountSystem.bean.Classification;
import AccountSystem.dao.ClassificationDao;
import AccountSystem.tools.SimpleTools;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.TextFieldListCell;
import javafx.stage.Stage;
​
import java.util.List;
​
/**
 * 添加分类界面控制器
 *
 * @author lck100
 */
public class AddClassificationFrameController {
    private ClassificationDao classificationDao = new ClassificationDao();
​
    private Stage dialogStage;
​
    public Stage getDialogStage() {
        return dialogStage;
    }
​
    public void setDialogStage(Stage dialogStage) {
        this.dialogStage = dialogStage;
    }
​
    @FXML
    private TextField inputClassificationNameTextField;
​
    @FXML
    private ListView<String> inputClassificationListView;
​
    @FXML
    private TextField outputClassificationNameTextField;
​
    @FXML
    private ListView<String> outputClassificationListView;
​
​
    /**
     * ”添加支出“按钮的事件监听器
     *
     * @param event 事件
     */
    public void addOutputButtonEvent(ActionEvent event) {
       
    }
​
    /**
     * “支出”右键菜单“编辑”的事件监听器
     *
     * @param event 事件
     */
    public void output_editContextMenuEvent(ActionEvent event) {
       
    }
​
    /**
     * “支出”右键菜单“删除”的事件监听器
     *
     * @param event 事件
     */
    public void output_deleteMenuItemEvent(ActionEvent event) {
       
    }
​
    /**
     * 支出分类界面”返回“按钮的事件监听器
     *
     * @param event 事件
     */
    public void outputClassificationReturnButtonEvent(ActionEvent event) {
       
    }
​
    /**
     * ”添加收入“按钮的事件监听器
     *
     * @param event 事件
     */
    public void addInputButtonEvent(ActionEvent event) {
       
    }
​
    /**
     * “收入”右键菜单“编辑”的事件监听器
     *
     * @param event 事件
     */
    public void input_editContextMenuEvent(ActionEvent event) {
       
    }
​
    /**
     * “收入”右键菜单“删除”的事件监听器
     *
     * @param event 事件
     */
    public void input_deleteContextMenuEvent(ActionEvent event) {
        
    }
​
    /**
     * 收入分类界面”返回“按钮的事件监听器
     *
     * @param event 事件
     */
    public void inputClassificationReturnButtonEvent(ActionEvent event) {
        
    }
​
    /**
     * “支出”分类列表视图编辑完成的事件监听器
     *
     * @param stringEditEvent 事件
     */
    public void outputClassificationListViewCommitEvent(ListView.EditEvent<String> stringEditEvent) {
       
    }
​
    /**
     * 收入分类列表视图编辑完成的事件监听器,按回车键完成对事件的响应
     *
     * @param stringEditEvent 事件
     */
    public void inputClassificationListViewCommitEvent(ListView.EditEvent<String> stringEditEvent) {
       
    }
​
}

其中的”getDialogStage()”和“setDialogStage()”就是将Stage传到该类中,然后在“返回”按钮事件中调用进行关闭窗口界面。

接着是在MainApp.java中创建方法加载FXML文件:

    /**
     * 操作结果:”添加分类“查询结果界面
     */
    public Scene initAddClassificationFrame() {
        try {
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(MainApp.class.getResource("view/addClassificationFrame.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);
​
            AddClassificationFrameController controller = loader.getController();
            controller.setDialogStage(mainFrameStage);
​
            mainFrameStage.showAndWait();
            return scene;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

最后是在菜单项事件中调用该方法:

    /**
     * ”添加分类“菜单项的事件监听器
     *
     * @param actionEvent 事件
     */
    @FXML
    public void addClassificationMenuItemEvent(ActionEvent actionEvent) {
        // 打开添加分类界面
        mainApp.initAddClassificationFrame();
    }

运行项目,查看创建完成的界面:

 

实现功能

首先在“支出分类列表”和“收入分类列表”中显示所有已存在的分类名称,即初始化列表项在initialize()方法中:

    /**
     * 初始化界面
     */
    public void initialize() {
        // 获取收入分类的所有信息
        List<Classification> inputClassificationList = new ClassificationDao().selectByType("收入");
        // 实例化一个一维数组
        String[] inputClassificationNames = new String[inputClassificationList.size()];
        // 将查询得到的分类名称装到一维数组中
        for (int i = 0; i < inputClassificationList.size(); i++) {
            inputClassificationNames[i] = inputClassificationList.get(i).getcName();
        }
        inputClassificationListView.setItems(FXCollections.observableArrayList(inputClassificationNames));
​
        // 获取支出分类的所有信息
        List<Classification> outputClassificationList = new ClassificationDao().selectByType("支出");
        // 实例化一个一维数组
        String[] outputClassificationNames = new String[outputClassificationList.size()];
        // 将查询得到的分类名称装到一维数组中
        for (int i = 0; i < outputClassificationList.size(); i++) {
            outputClassificationNames[i] = outputClassificationList.get(i).getcName();
        }
        outputClassificationListView.setItems(FXCollections.observableArrayList(outputClassificationNames));
    }

下面就是实现“添加”功能了,通过界面上的“添加支出”和“添加收入”来实现,获取界面用户输入的分类名称,然后将其插入到数据库表中并且下面的列表也进行更新显示。

所以“添加支出”按钮的事件监听器代码如下:

    /**
     * ”添加支出“按钮的事件监听器
     *
     * @param event 事件
     */
    public void addOutputButtonEvent(ActionEvent event) {
        // 获取用户输入的支出分类名称
        String output = outputClassificationNameTextField.getText();
        // 判断用户是否输入为空
        if (null == output || "".equals(output)) {
            SimpleTools.informationDialog(Alert.AlertType.WARNING, "提示", "警告", "文本框内容不能为空!");
        } else {
            // 列表视图添加用户输入的支出分类重名
            outputClassificationListView.getItems().add(output);
            // 封装要添加的分类实体类数据
            Classification classification = new Classification(output, "支出");
            // 进行添加操作
            boolean b = classificationDao.addClassification(classification);
            outputClassificationNameTextField.setText("");
        }
​
    }

“添加收入”按钮的事件监听器代码如下:

    /**
     * ”添加收入“按钮的事件监听器
     *
     * @param event 事件
     */
    public void addInputButtonEvent(ActionEvent event) {
        // 获取用户输入的收入分类
        String input = inputClassificationNameTextField.getText();
        // 判断用户是否输入为空
        if (null == input || "".equals(input)) {
            SimpleTools.informationDialog(Alert.AlertType.WARNING, "提示", "警告", "文本框内容不能为空!");
        } else {
            // 向列表视图添加收入分类
            inputClassificationListView.getItems().add(input);
            // 向数据库中添加收入分类
            classificationDao.addClassification(new Classification(input, "收入"));
            // 清空用户输入
            inputClassificationNameTextField.setText("");
        }
    }

“返回”按钮的功能是退出这个界面,即关闭该Stage,方法代码如下:

    /**
     * 支出分类界面”返回“按钮的事件监听器
     *
     * @param event 事件
     */
    public void outputClassificationReturnButtonEvent(ActionEvent event) {
        // 关闭该界面
        dialogStage.close();
    }
​
    /**
     * 收入分类界面”返回“按钮的事件监听器
     *
     * @param event 事件
     */
    public void inputClassificationReturnButtonEvent(ActionEvent event) {
        dialogStage.close();
    }

除了添加分类之外,肯定还有删除和编辑分类。

删除分类就是在列表视图中选中要删除的列表项,然后右键单击选中删除,即可删除该项并从数据库中也进行 删除。

所以“支出分类”界面的“删除”右键菜单事件方法如下:

    /**
     * “支出”右键菜单“删除”的事件监听器
     *
     * @param event 事件
     */
    public void output_deleteMenuItemEvent(ActionEvent event) {
        // 获取用户选中的支出分类
        String outputItem = (String) outputClassificationListView.getSelectionModel().getSelectedItem();
        // 确认用户是否要删除
        boolean b = SimpleTools.informationDialog(Alert.AlertType.CONFIRMATION, "确认", "确认", "请问是否确认删除名为" + outputItem + "的支出分类?");
        if (b) {
            // 从列表视图中移除该分类
            outputClassificationListView.getItems().remove(outputItem);
            // 从数据库中删除该分类
            classificationDao.deleteClassification(new Classification(outputItem, "支出"));
        }
    }

“收入分类“界面的”删除“右键菜单事件方法如下:

    /**
     * “收入”右键菜单“删除”的事件监听器
     *
     * @param event 事件
     */
    public void input_deleteContextMenuEvent(ActionEvent event) {
        // 获取用户输入的收入分类
        String inputItem = (String) inputClassificationListView.getSelectionModel().getSelectedItem();
        boolean b = SimpleTools.informationDialog(Alert.AlertType.CONFIRMATION, "确认", "确认", "请问是否确认删除名为" + inputItem + "的收入分类?");
        if (b) {
            // 向列表视图中移除该收入分类
            inputClassificationListView.getItems().remove(inputItem);
            // 向数据库中删除该收入分类
            classificationDao.deleteClassification(new Classification(inputItem, "收入"));
        }
    }

而编辑列表项稍微要难些,先要通过右键菜单“编辑”使列表项可以编辑,然后通过“ListView.EditEvent<String>”事件来获取修改后的值进行更新操作。

所以“支出分类”界面的编辑事件代码如下:

    /**
     * “支出”右键菜单“编辑”的事件监听器
     *
     * @param event 事件
     */
    public void output_editContextMenuEvent(ActionEvent event) {
        outputClassificationListView.setCellFactory(TextFieldListCell.forListView());
        outputClassificationListView.setEditable(true);
        outputClassificationListView.setFocusTraversable(true);
    }
​
    /**
     * “支出”分类列表视图编辑完成的事件监听器
     *
     * @param stringEditEvent 事件
     */
    public void outputClassificationListViewCommitEvent(ListView.EditEvent<String> stringEditEvent) {
        // 获取列表视图选中的原值
        String sourceValue = stringEditEvent.getSource().getSelectionModel().getSelectedItem();
        // 获取列表视图编辑后的新值
        String newValue = stringEditEvent.getNewValue();
        // 向列表视图移除原值
        outputClassificationListView.getItems().remove(sourceValue);
        // 向列表视图添加新值
        outputClassificationListView.getItems().add(newValue);
        // 向数据库更新值
        classificationDao.updateClassification(newValue, sourceValue);
    }

“收入分类“界面中的编辑事件代码如下:

    /**
     * “收入”右键菜单“编辑”的事件监听器
     *
     * @param event 事件
     */
    public void input_editContextMenuEvent(ActionEvent event) {
        inputClassificationListView.setCellFactory(TextFieldListCell.forListView());
        inputClassificationListView.setEditable(true);
        inputClassificationListView.setFocusTraversable(true);
    }
    
        /**
     * 收入分类列表视图编辑完成的事件监听器,按回车键完成对事件的响应
     *
     * @param stringEditEvent 事件
     */
    public void inputClassificationListViewCommitEvent(ListView.EditEvent<String> stringEditEvent) {
        // 获取列表视图选中的原值
        String sourceValue = stringEditEvent.getSource().getSelectionModel().getSelectedItem();
        // 获取列表视图编辑后的新值
        String newValue = stringEditEvent.getNewValue();
        // 向列表视图移除原值
        inputClassificationListView.getItems().remove(sourceValue);
        // 向列表视图添加新值
        inputClassificationListView.getItems().add(newValue);
        // 向数据库更新值
        classificationDao.updateClassification(newValue, sourceValue);
    }

添加分类界面的逻辑功能已经实现,能够完成对分类的增加、删除和编辑。

运行代码,测试功能:

 

 

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

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

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值