zoukankan      html  css  js  c++  java
  • JavaFx TableView(表格控件)与Pagination(分页控件)结合

    一个完善的数据查询界面,是不能没有分页的

    效果:

    框架:SpringBoot+JavaFx+Hibernate

    fxml:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.geometry.*?>
    <?import javafx.scene.control.*?>
    <?import java.lang.*?>
    <?import javafx.scene.layout.*?>
    
    
    <BorderPane maxHeight="-Infinity" maxWidth="-Infinity"
                minHeight="-Infinity" minWidth="-Infinity"
                prefHeight="600.0" prefWidth="800.0"
                xmlns="http://javafx.com/javafx/8"
                xmlns:fx="http://javafx.com/fxml/1"
                fx:controller="com.maxinhai.world.controller.DynamicTableViewController">
       <top>
          <HBox prefHeight="42.0" prefWidth="800.0" BorderPane.alignment="CENTER">
             <children>
                <Button mnemonicParsing="false" text="首页" onAction="#toIndex">
                   <HBox.margin>
                      <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
                   </HBox.margin>
                </Button>
                <Button mnemonicParsing="false" text="新增">
                   <HBox.margin>
                      <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
                   </HBox.margin>
                </Button>
                <Button mnemonicParsing="false" text="查询">
                   <HBox.margin>
                      <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
                   </HBox.margin>
                </Button>
                <Button mnemonicParsing="false" text="修改">
                   <HBox.margin>
                      <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
                   </HBox.margin>
                </Button>
                <Button mnemonicParsing="false" text="删除">
                   <HBox.margin>
                      <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
                   </HBox.margin>
                </Button>
             </children>
          </HBox>
       </top>
       <center>
          <VBox prefHeight="200.0" prefWidth="100.0" BorderPane.alignment="CENTER">
             <children>
                <HBox prefHeight="43.0" prefWidth="800.0">
                   <children>
                      <Label id="codeLabel" fx:id="codeLabel" alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefWidth="75.0" text="编码:" textAlignment="CENTER">
                         <HBox.margin>
                            <Insets bottom="10.0" left="10.0" top="10.0" />
                         </HBox.margin>
                      </Label>
                      <TextField id="codeText" prefWidth="180.0" fx:id="coedTextField">
                         <HBox.margin>
                            <Insets bottom="5.0" right="5.0" top="5.0" />
                         </HBox.margin>
                      </TextField>
                      <Label id="nameLabel" fx:id="nameLabel" alignment="CENTER_RIGHT" contentDisplay="RIGHT" prefWidth="75.0" text="名称:" textAlignment="CENTER">
                         <HBox.margin>
                            <Insets bottom="10.0" left="20.0" top="10.0" />
                         </HBox.margin>
                      </Label>
                      <TextField id="codeText" prefWidth="180.0" fx:id="nameTextField">
                         <HBox.margin>
                            <Insets bottom="5.0" right="5.0" top="5.0" />
                         </HBox.margin>
                      </TextField>
                   </children>
                </HBox>
                <HBox prefHeight="42.0" prefWidth="800.0">
                   <children>
                      <Label text="开始时间:">
                         <HBox.margin>
                            <Insets bottom="10.0" left="10.0" top="10.0" />
                         </HBox.margin>
                      </Label>
                      <DatePicker prefWidth="180.0" fx:id="beginDatePicker">
                         <HBox.margin>
                            <Insets bottom="5.0" right="5.0" top="5.0" />
                         </HBox.margin>
                      </DatePicker>
                      <Label text="结束时间:">
                         <HBox.margin>
                            <Insets bottom="10.0" left="20.0" top="10.0" />
                         </HBox.margin>
                      </Label>
                      <DatePicker prefWidth="180.0" fx:id="endDatePicker">
                         <HBox.margin>
                            <Insets bottom="5.0" right="5.0" top="5.0" />
                         </HBox.margin>
                      </DatePicker>
                   </children>
                </HBox>
                <HBox prefHeight="473.0" prefWidth="800.0" fx:id="parent">
                   <children>
                      <!--实现分页插件与表格控件结合的关键在于两者要在同一个父容器下-->
                      <TableView prefHeight="100.0" prefWidth="802.0" fx:id="tableView" />
                      <Pagination fx:id="pagination" pageCount="10" prefHeight="35.0" prefWidth="800.0" BorderPane.alignment="CENTER" />
                   </children>
                </HBox>
             </children>
          </VBox>
       </center>
       <bottom>
          <!--错误位置-->
          <!--<Pagination fx:id="pagination" pageCount="10" prefHeight="35.0" prefWidth="800.0" BorderPane.alignment="CENTER" />-->
       </bottom>
    </BorderPane>

    controller:

    import com.maxinhai.world.WorldApplication;
    import com.maxinhai.world.entity.ClientClockInRecord;
    import com.maxinhai.world.repository.ClientClockInRepository;
    import com.maxinhai.world.service.impl.DynamicTableViewServiceImpl;
    import com.maxinhai.world.utils.ModuleUtils;
    import de.felixroske.jfxsupport.FXMLController;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.Node;
    import javafx.scene.control.*;
    import javafx.scene.layout.HBox;
    import javafx.util.Callback;
    import org.springframework.beans.factory.annotation.Autowired;
    
    import java.net.URL;
    import java.util.*;
    
    /**
     * @program: world
     * @description: 动态表格控制器
     * @author: XinHai.Ma
     * @create: 2021-05-24 14:33
     */
    @FXMLController
    public class DynamicTableViewController extends BaseController implements Initializable {
    
        @FXML
        private TextField coedTextField;
        @FXML
        private TextField nameTextField;
        @FXML
        private Label codeLabel;
        @FXML
        private Label nameLabel;
        @FXML
        private DatePicker beginDatePicker;
        @FXML
        private DatePicker endDatePicker;
        @FXML
        private TableView<ClientClockInRecord> tableView;
        @FXML
        private HBox parent;
        @FXML
        private Pagination pagination;
    
        // 删除集合
        private List<String> deleteList = new ArrayList<>();
        // 编辑集合
        private List<String> updateList = new ArrayList<>();
    
        @Autowired
        private ClientClockInRepository clockInRepository;
        @Autowired
        private DynamicTableViewServiceImpl dynamicTableViewService;
    
        @Override
        public void initialize(URL location, ResourceBundle resources) {
            // 初始化表格
            LinkedHashMap<String, String> columns = new LinkedHashMap<>();
            columns.put("gid", "主键");
            columns.put("clientId", "员工id");
            columns.put("clientName", "员工名称");
            columns.put("workStatus", "状态");
            columns.put("createBy", "创建者");
            columns.put("createTime", "创建时间");
            columns.put("editBy", "编辑者");
            columns.put("editTime", "编辑时间");
            List<TableColumn> columnList = ModuleUtils.createColumn(true, columns, deleteList, updateList);
            HashMap<String, Object> params = new HashMap<>();
            params.put("pageIndex", 1);
            params.put("pageSize", 28);
            Map<String, Object> result = dynamicTableViewService.select(params);
            List<ClientClockInRecord> dataList = (List<ClientClockInRecord>)result.get("data"); //clockInRepository.findAll();
            ModuleUtils.createDynamicTable(parent, tableView, columnList, dataList);
    
            // 初始化分页插件
            pagination.setCurrentPageIndex(0);
            pagination.setPageCount(Integer.valueOf(result.get("total").toString()));
            pagination.setPageFactory(new Callback<Integer, Node>() {
                @Override
                public Node call(Integer pageIndex) {
                    return createPage(pageIndex);
                }
            });
            // 分页插件宽度(不设置分页插件宽度表格宽度也无法随窗口变化)
            WorldApplication.getScene().widthProperty().addListener(new ChangeListener<Number>() {
                @Override
                public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                    pagination.setPrefWidth(newValue.doubleValue());
                }
            });
        }
    
    
        /**
         * 页面切换调用该方法
         * @param pageIndex
         * @return
         */
        private TableView<ClientClockInRecord> createPage(int pageIndex) {
            HashMap<String, Object> params = new HashMap<>();
            params.put("pageIndex", pageIndex);
            params.put("pageSize", 28);
            Map<String, Object> result = dynamicTableViewService.select(params);
            List<ClientClockInRecord> dataList = (List<ClientClockInRecord>)result.get("data");
            ObservableList<ClientClockInRecord> items = FXCollections.observableArrayList(dataList);
            tableView.setItems(items);
            return tableView;
        }
    
    
        @FXML
        public void select () {
            HashMap<String, Object> params = new HashMap<>();
            Map<String, Object> result = dynamicTableViewService.select(params);
            List<ClientClockInRecord> dataList = (List<ClientClockInRecord>)result.get("data");
        }
    
    }

    service:

    import com.maxinhai.world.entity.ClientClockInRecord;
    import com.maxinhai.world.repository.ClientClockInRepository;
    import com.maxinhai.world.service.DynamicTableViewService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.PageRequest;
    import org.springframework.data.domain.Sort;
    import org.springframework.data.jpa.domain.Specification;
    import org.springframework.stereotype.Service;
    
    import javax.persistence.criteria.CriteriaBuilder;
    import javax.persistence.criteria.CriteriaQuery;
    import javax.persistence.criteria.Predicate;
    import javax.persistence.criteria.Root;
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    import java.util.*;
    import java.util.stream.Collectors;
    
    /**
     * @program: world
     * @description: 动态表格业务层
     * @author: XinHai.Ma
     * @create: 2021-05-24 15:03
     */
    @SuppressWarnings("all")
    @Service
    public class DynamicTableViewServiceImpl implements DynamicTableViewService {
    
        @Autowired
        private ClientClockInRepository clockInRepository;
    
        @Override
        public Map<String, Object> select(Map<String, Object> params) {
            String pageIndex = params.get("pageIndex").toString();
            String pageSize = params.get("pageSize").toString();
            PageRequest page = PageRequest.of(Integer.valueOf(pageIndex), Integer.valueOf(pageSize), Sort.Direction.DESC, "createTime");
            Page<ClientClockInRecord> recordPage = clockInRepository.findAll(new Specification<ClientClockInRecord>() {
                @Override
                public Predicate toPredicate(Root<ClientClockInRecord> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                    List<Predicate> condition = new ArrayList<Predicate>();
                    condition.add(criteriaBuilder.equal(root.get("isDelete").as(Integer.class), 0));
                    condition.add(criteriaBuilder.equal(root.get("isActive").as(Integer.class), 0));
                    // 编号
                    if (Objects.nonNull(params.get("code"))) {
                        condition.add(criteriaBuilder.equal(root.get("code").as(String.class), params.get("code").toString()));
                    }
                    // 名称
                    if (Objects.nonNull(params.get("name"))) {
                        condition.add(criteriaBuilder.equal(root.get("name").as(String.class), params.get("name").toString()));
                    }
                    // 开始、结束时间
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                    if (Objects.nonNull(params.get("beginTime")) && Objects.nonNull(params.get("endTime"))) {
                        // 开始时间和结束时间之内
                        String beginTime = params.get("beginTime").toString() + " 00:00:00";
                        String endTime = params.get("endTime").toString() + " 23:59:59";
                        condition.add(criteriaBuilder.between(root.<LocalDateTime>get("createTime"), LocalDateTime.parse(beginTime, formatter), LocalDateTime.parse(endTime, formatter)));
                    } else if (Objects.nonNull(params.get("beginTime"))) {
                        // 大于开始时间
                        String beginTime = params.get("beginTime").toString() + " 00:00:00";
                        condition.add(criteriaBuilder.greaterThanOrEqualTo(root.<LocalDateTime>get("createTime"), LocalDateTime.parse(beginTime, formatter)));
                    } else if (Objects.nonNull(params.get("endTime"))) {
                        // 小于结束时间
                        String beginTime = params.get("endTime").toString() + " 23:59:59";
                        condition.add(criteriaBuilder.lessThanOrEqualTo(root.<LocalDateTime>get("createTime"), LocalDateTime.parse(beginTime, formatter)));
                    }
                    Predicate[] p = new Predicate[condition.size()];
                    return criteriaBuilder.and(condition.toArray(p));
                }
            }, page);
            Map<String, Object> result = new HashMap<>();
            result.put("data", recordPage.get().collect(Collectors.toList()));
            result.put("total", recordPage.getTotalPages());
            return result;
        }
    
    }

    dao:

    import com.maxinhai.world.entity.ClientClockInRecord;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
    import org.springframework.data.jpa.repository.Query;
    import org.springframework.data.repository.query.Param;
    import org.springframework.stereotype.Repository;
    
    import java.util.List;
    
    @Repository
    public interface ClientClockInRepository extends JpaRepository<ClientClockInRecord, String>, JpaSpecificationExecutor<ClientClockInRecord> {
    
    }

    组件初始化代码:

        /**
         * 方法描述:根据columnList(表头集合)、dataList(数据集合)初始化tableView
         * 注意:设置TableView的宽高去适应界面的大小行不通,只能设置父元素的大小,让TableView自适应
         *
         * @param parentNode  父容器
         * @param tableView  tableView对象
         * @param columnList 表格字段集合
         * @param dataList   表格数据集合
         */
        public static void createDynamicTable(Pane parentNode, TableView tableView, List<TableColumn> columnList, List dataList) {
            AssertUtils.assertTrue(Objects.isNull(tableView), "Component is Null!");
            // 设置表格可编辑
            tableView.setEditable(true);
            // 设置多选
            tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
            // 去掉空白多于列
            tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
            // 设置表头
            tableView.getColumns().addAll(columnList);
            // 更新表格数据
            ObservableList<ClientLoginRecord> data = FXCollections.observableArrayList(dataList);
            tableView.setItems(data);
            // 使tableView随窗口变化而变化
            WorldApplication.getScene().heightProperty().addListener(new ChangeListener<Number>() {
                @Override
                public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                    parentNode.setPrefHeight(newValue.doubleValue());
                }
            });
            WorldApplication.getScene().widthProperty().addListener(new ChangeListener<Number>() {
                @Override
                public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                    tableView.setPrefWidth(newValue.doubleValue());
                }
            });
        }
    
    
        /**
         * 根据isCheckBox、columns创建表格表头
         *
         * @param isCheckBox 是否创建多选列
         * @param columns    bean字段对应中文集合
         * @return
         */
        public static List<TableColumn> createColumn(boolean isCheckBox, LinkedHashMap<String, String> columns, List<String> delList, List<String> updList) {
            List<TableColumn> columnList = new ArrayList<>();
            // 多选框
            if (isCheckBox) {
                TableColumn<BaseEntity, CheckBox> checkCol = new TableColumn("单选框");
                checkCol.setMinWidth(30);
                checkCol.setMinWidth(30);
                checkCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<BaseEntity, CheckBox>, ObservableValue<CheckBox>>() {
                    @Override
                    public ObservableValue<CheckBox> call(TableColumn.CellDataFeatures<BaseEntity, CheckBox> param) {
                        CheckBox checkBox = new CheckBox();
                        // 设置checkBox居中,貌似没用
                        checkBox.setAlignment(Pos.CENTER);
                        checkBox.setOnAction(event -> {
                            boolean selected = checkBox.isSelected();
                            String gid = param.getValue().getGid();
                            if (selected) {
                                delList.add(gid);
                                updList.removeAll(updList);
                                updList.add(gid);
                                System.out.println("选中: " + gid);
                            } else {
                                delList.remove(gid);
                                updList.remove(gid);
                                System.out.println("取消选中: " + gid);
                            }
                        });
                        return new ReadOnlyObjectWrapper<CheckBox>(checkBox);
                    }
                });
                columnList.add(checkCol);
            }
    
            // 序号列
            TableColumn seqCol = new TableColumn("序号");
            seqCol.setMinWidth(20);
            seqCol.setMinWidth(20);
            seqCol.setCellFactory(new IDCell<>());
            columnList.add(seqCol);
    
            Map<String, Double> defaultWidthMap = getDefaultWidthMap();
    
            // 创建其他表头
            columns.forEach((k, v) -> {
                TableColumn column = new TableColumn(v);
                if ("gid".equals(k)) {
                    column.setVisible(false);
                }
                if (getDateColSet().contains(k)) {
                    formatDateTimeCol(column);
                }
                if (Objects.isNull(defaultWidthMap.get(k))) {
                    // 没有默认长度,设置100宽度
                    column.setMinWidth(100);
                } else {
                    column.setMinWidth(defaultWidthMap.get(k));
                }
                column.setCellValueFactory(new PropertyValueFactory<ClientLoginRecord, String>(k));
                columnList.add(column);
            });
            return columnList;
        }
    
    
        /**
         * 格式化时间字段(Java8)
         *
         * @param column
         */
        public static void formatDateTimeCol(TableColumn column) {
            DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            column.setCellFactory(data -> {
                TableCell<Object, LocalDateTime> cell = new TableCell<Object, LocalDateTime>() {
                    @Override
                    protected void updateItem(LocalDateTime item, boolean empty) {
                        super.updateItem(item, empty);
                        if (empty) {
                            setText(null);
                        } else {
                            if (item != null)
                                this.setText(format.format(item));
                        }
                    }
                };
                return cell;
            });
        }
    
    
        /**
         * 格式化时间字段(Java7)
         *
         * @param column
         */
        public static void formatDateCol(TableColumn column) {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            column.setCellFactory(data -> {
                TableCell<Object, Date> cell = new TableCell<Object, Date>() {
                    @Override
                    protected void updateItem(Date item, boolean empty) {
                        super.updateItem(item, empty);
                        if (empty) {
                            setText(null);
                        } else {
                            if (item != null)
                                this.setText(format.format(item));
                        }
                    }
                };
                return cell;
            });
        }
    
    
        /**
         * 获取时间字段集合
         *
         * @return
         */
        public static Set<String> getDateColSet() {
            Set<String> colSet = new HashSet<>();
            colSet.add("createTime");
            colSet.add("editTime");
            return colSet;
        }
    
    
        /**
         * 刷新tableView
         *
         * @param tableView
         * @param dataList
         */
        public static void refresh(TableView tableView, List dataList) {
            ObservableList items = tableView.getItems();
            items.removeAll(items);
            items.addAll(dataList);
            tableView.refresh();
        }
    
    
        /**
         * 获取默认字段对应长度集合
         *
         * @return
         */
        public static Map<String, Double> getDefaultWidthMap() {
            Map<String, Double> map = new HashMap<>();
            map.put("gid", 350.00);
            map.put("account", 100.00);
            map.put("code", 100.00);
            map.put("description", 100.00);
            map.put("remark", 100.00);
            map.put("createBy", 100.00);
            map.put("createTime", 200.00);
            map.put("editBy", 100.00);
            map.put("editTime", 200.00);
            map.put("username", 200.00);
            map.put("password", 200.00);
            return map;
        }
  • 相关阅读:
    负载均衡
    二叉树反转
    hashMap 和红黑树
    linux c++ 服务器编程,收藏一个测试例子
    某某音乐盒面试
    Linux中的文件i节点
    linux 文件格式压缩
    类string的构造函数、拷贝构造函数和析构函数
    计算二叉树的深度
    string转换为decimal
  • 原文地址:https://www.cnblogs.com/mxh-java/p/14805389.html
Copyright © 2011-2022 走看看