如何将JTableModel横向展示客房预订数据?
如何将JTable的纵向预订数据转换为横向房间-日期矩阵展示?
当前问题
通过查询获取了包含日期(Tarikh)和房间(Room)的ResultSet,涉及9间客房,时间范围为2022年1月1日至1月31日。使用net.proteanit.sql.DbUtils将ResultSet转换为JTableModel后,表格是纵向结构:
Room Date Booked 101 2022-01-01 2022-01-01 102 2022-01-01 2022-01-01 103 2022-01-01 2022-01-01 104 2022-01-01 2022-01-01 105 2022-01-01 null 106 2022-01-01 null 107 2022-01-01 null 108 2022-01-01 null 109 2022-01-01 null 101 2022-01-02 null 102 2022-01-02 2022-01-02 ...(以此类推)
需要改成横向结构:以房间号为行、日期为列,已预订单元格标记为X,示例如下:
0101 0201 0301 0401 0501 ... 101 X 102 X X 103 X 104 X 105 106 107 108 109
实现步骤
1. 从ResultSet提取并整理数据
先遍历ResultSet,把房间号、日期以及对应的预订信息整理到集合和Map中,方便后续构建模型:
import java.sql.ResultSet; import java.sql.Date; import java.time.LocalDate; import java.util.*; // 初始化存储结构 Set<String> rooms = new TreeSet<>(); // TreeSet保证房间号有序 Set<LocalDate> dates = new TreeSet<>(); // TreeSet保证日期有序 Map<String, Set<LocalDate>> roomBookings = new HashMap<>(); // 遍历ResultSet提取数据 while (resultSet.next()) { String roomNum = resultSet.getString("Room"); LocalDate date = resultSet.getDate("Date").toLocalDate(); Date bookedDateSql = resultSet.getDate("Booked"); LocalDate bookedDate = bookedDateSql != null ? bookedDateSql.toLocalDate() : null; // 记录房间和日期 rooms.add(roomNum); dates.add(date); // 初始化当前房间的预订集合 roomBookings.computeIfAbsent(roomNum, k -> new HashSet<>()); // 如果已预订,添加日期到集合 if (bookedDate != null) { roomBookings.get(roomNum).add(bookedDate); } } // 转成有序列表方便后续使用 List<String> roomList = new ArrayList<>(rooms); List<LocalDate> dateList = new ArrayList<>(dates);
2. 自定义JTableModel
继承AbstractTableModel,按照横向矩阵的逻辑实现方法:
import javax.swing.table.AbstractTableModel; import java.util.List; import java.util.Map; import java.util.Set; import java.time.LocalDate; class RoomBookingTableModel extends AbstractTableModel { private final List<String> roomList; private final List<LocalDate> dateList; private final Map<String, Set<LocalDate>> roomBookings; public RoomBookingTableModel(List<String> roomList, List<LocalDate> dateList, Map<String, Set<LocalDate>> roomBookings) { this.roomList = roomList; this.dateList = dateList; this.roomBookings = roomBookings; } @Override public int getRowCount() { return roomList.size(); // 行数等于房间数 } @Override public int getColumnCount() { return 1 + dateList.size(); // 第一列是房间号,后面是日期列 } @Override public String getColumnName(int column) { if (column == 0) { return "房间号"; } // 将日期格式化为MMdd格式(比如0101) LocalDate targetDate = dateList.get(column - 1); return String.format("%02d%02d", targetDate.getMonthValue(), targetDate.getDayOfMonth()); } @Override public Object getValueAt(int rowIndex, int columnIndex) { String currentRoom = roomList.get(rowIndex); if (columnIndex == 0) { return currentRoom; } // 获取当前列对应的日期 LocalDate targetDate = dateList.get(columnIndex - 1); // 检查该房间是否在该日期预订,是则返回X,否则返回空字符串 return roomBookings.get(currentRoom).contains(targetDate) ? "X" : ""; } }
3. 应用自定义模型到JTable
最后把自定义模型设置给JTable即可:
import javax.swing.JTable; RoomBookingTableModel customModel = new RoomBookingTableModel(roomList, dateList, roomBookings); JTable bookingTable = new JTable(customModel);
内容的提问来源于stack exchange,提问作者Hussin S Mohamed
相关产品推荐
相关产品推荐

