大作业-简易购物车

简易购物车

1. 效果展示

均为gif,加载过程请耐心等待

1098869-20171104162729591-1129320944.gif

1098869-20171104163354029-2080190930.gif

1098869-20171104163523482-782465519.gif

1098869-20171104163820857-1738969658.gif

1098869-20171104163850013-134657344.gif

2. 细节介绍

源码地址:https://github.com/dongmingchao/JavaPTA/blob/master/src/six/ShoppingCartDemo2.java

1. 使用JavaFX,JavaFX的特性就是fxml,从fxml中读取布局

使用lookup方法

先读入资源

        VBox buyGood = FXMLLoader.load(getClass().getResource("good.fxml"));

然后使用lookup,参数和web开发时候的jQuery选择器类似,据说支持类选择器,但是支持好像不完整,所以这里仅仅使用id选择器

        TableView<cartItem> goodList = (TableView<cartItem>) buyGood.lookup("#goodList");

要在fxml中如下定义fx:id

1098869-20171104183545138-921508346.png

2. 使用TableView展示商品

1098869-20171104184031295-14820680.png

为什么使用TableView:这里“数量”一项包含两个按钮,由于ListView不能在每个项中增加按钮或者其他Object,但是TableView却可以,所以才使用TableView

1. 新建TableView,然后使用setItems方法设置让TableView显示的数据

这里数据要求封装成ObservableList对象,我们可以如下生成一个ObservableList对象

        ObservableList<cartItem> goodItems = FXCollections.observableArrayList();
        goodList.setItems(goodItems);

但是注意我们并没有指出哪一列使用哪个属性,所以需要指明列显示数据对应的属性名

        goodList.getColumns().get(0).setCellValueFactory(new PropertyValueFactory<>("name"));
        goodList.getColumns().get(1).setCellValueFactory(new PropertyValueFactory<>("singlePrice"));
        goodList.getColumns().get(2).setCellValueFactory(new PropertyValueFactory<>("numberTF"));

goodItems中放的是cartItem对象,我们来看cartItem对象的属性是如何建立的

    private StringProperty name = new SimpleStringProperty();
    private IntegerProperty number = new SimpleIntegerProperty();
    private DoubleProperty price = new SimpleDoubleProperty();
    private DoubleProperty singlePrice = new SimpleDoubleProperty();
    private ObjectProperty<VBox> numberTF;
    private Label theNumber;
    private Button subNumber;

注意这里的变量名,和上一段代码中PropertyValueFactory函数的构建参数是一样的,这一点务必牢记,这是一种简单的构造Table单元格的方法。这样就可以在goodItems中调用add方法添加cartItem对象,同时在第一列显示name属性,在第二列显示singlePrice属性,在第三列显示numberTF属性
⚠️所有要展示的属性(例如上面的name,singlePrice,numberTF)都需要生成getter和setter,这是内部建立TableCell的必需方法

2. 构建含有Button的数量属性

我们注意到上面的代码中有个叫做numberTF的ObjectProperty,所以就是在初始化的时候给这个属性一个pane值来放Button,我使用的是VBox这个pane类

        addNumber = new Button("+");
        subNumber = new Button("-");
        theNumber = new Label(number.toString());
        numberTF = new SimpleObjectProperty<>(new VBox(addNumber,theNumber,subNumber));

在Button点击的时候要改变变量number的值,LabeltheNumber显示的值,同时要根据numbersinglePrice的值计算price的值,所以我直接写进一个setNumber里,从而实现数据动态绑定。
⚠️使用BigDecimal计算,避免出现3x1.2=3.599999的情况

    public void setNumber(int number) {
        this.number.set(number);
        if (theNumber!=null) theNumber.setText(String.valueOf(number));
        this.setPrice(BigDecimal.valueOf(singlePrice.get()).multiply(BigDecimal.valueOf(number)).doubleValue());
    }

和Button点击绑定的函数我一起写进了构造器,根据我的设计,在购物车中的cartItem在数量变为0的时候会自动被删除,而在商品列表的cartItem数量最低可以为0,再点击的时候就会无效,显然这个处理点击时候的传入数字的操作是不一样的,所以我将它抽象出来。下面附带我的构造函数。

    abstract void calcButton(int number);

    public cartItem(String name, Integer number, double singlePrice) {
        this.setName(name);
        this.setSinglePrice(singlePrice);
        this.setNumber(number);
        addNumber = new Button("+");
        subNumber = new Button("-");
        theNumber = new Label(number.toString());
        theNumber.setStyle("-fx-font-size: 20px");//fxcss设置字体大小为20px
        numberTF = new SimpleObjectProperty<>(new VBox(addNumber,theNumber,subNumber));
        subNumber.setOnAction(event -> calcButton(this.getNumber() - 1));
        addNumber.setOnAction(event -> calcButton(this.getNumber() + 1));
    }

这里附带说一种利用fxml设置触发方法的方式:在fxml中使用onAction="#FunctionName"方法,编译时会根据fx:controller指向的类中寻找方法并绑定。
例如我在fxml中最外层父容器的属性如下:

<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="557.0" prefWidth="330.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="six.Controller">

此时被绑定的类就是six.Controller,在此类中实现backTo方法,然后就可以如下使用

            <Button fx:id="watch" mnemonicParsing="false" text="我选择观望" onAction="#backTo"/>

将backTo方法绑定到变量名是watch的Button上,对于Button来说Action就是在被点击的时候触发,对于TextField就是编辑时敲击回车触发。

3. 关于Controller

可能有人就会问了,fxml取Controller中的方法学会了,但是如果在代码中取对应的Controller呢?在JavaFX中有个对应的FXMLLoader类,创建该类的对象后,可以使用该对象取到fxml中的控件和Controller。具体代码如下

        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource("cart.fxml"));
        VBox root = loader.load();
        controller = loader.getController();

先码到这里,以后慢慢补,个人网站搭建中,到时候会放到那里,也会放一些其他的东西。
本次就算是抛砖引玉,将我踩过的坑列出一些,希望对你有所帮助,代码仓促,码风dirty,轻喷

转载于:https://www.cnblogs.com/DedSec/p/7783789.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值