JavaFX如何给TableView单行新增列并添加ProgressIndicator
解决方案
问题根源
你的代码存在两个核心问题:
- 每次点击「Add」时都向
tableOfProcesses.getItems()中添加新的Process对象,导致表格行数不断增加,违背了「始终仅保留一行」的需求。 TableColumn的cellValueFactory绑定的是Process的progressIndicator属性,这意味着每一行的该列单元格会显示对应行Process的进度指示器,但你需要的是每个列拥有独立的进度指示器,且仅显示一行。
修复代码
1. 初始化表格(确保始终只有一行)
在控制器的initialize方法中,先向表格添加一行空数据(仅用于渲染单元格):
@Override public void initialize(URL url, ResourceBundle rb) { // 添加一行空对象,保证表格始终有一行可显示单元格 tableOfProcesses.getItems().add(new Object()); // 其他初始化逻辑... }
2. 修改AddNewColToTable方法
不再向表格添加新行,而是为每个新列创建自定义TableCell,直接在单元格中生成独立的ProgressIndicator:
private void AddNewColToTable(int CPUTimeRequested) { Process newProcess = new Process(CPUTimeRequested); this.listOfProcesses.add(newProcess); // 创建新列,标题为进程ID TableColumn<Object, Void> newCol = new TableColumn<>("P" + newProcess.GetId()); // 自定义单元格,生成独立的进度指示器 newCol.setCellFactory(column -> new TableCell<Object, Void>() { // 为该列单元格创建专属的ProgressIndicator private final ProgressIndicator progressIndicator = new ProgressIndicator(); @Override protected void updateItem(Void item, boolean empty) { super.updateItem(item, empty); if (empty) { setGraphic(null); } else { // 可选:将进度指示器与Process的进度属性绑定(需Process类提供对应属性) // 例如Process有DoubleProperty类型的progress属性: // progressIndicator.progressProperty().bind(newProcess.progressProperty()); setGraphic(progressIndicator); } } }); this.tableOfProcesses.getColumns().add(newCol); this.m_NumOfCols++; // 无需调用addAll(data)和refresh,表格已有一行数据 }
3. 简化OnAddButtonPressed方法
去掉原本向表格添加行数据的逻辑(现在表格始终只有一行),其他校验逻辑保持不变:
@FXML private void OnAddButtonPressed(ActionEvent event) { int currentCPUTimeRequestedInteger; String currentCPUTimeRequested = this.addTextField.getText(); // 输入校验逻辑保持不变 if(currentCPUTimeRequested.isEmpty() || currentCPUTimeRequested.length() > 1 || !Character.isDigit(currentCPUTimeRequested.toCharArray()[0]) || currentCPUTimeRequested.toCharArray()[0] == '0') { PopAddButtonError(); return; } if(m_NumOfCols == MAX_NUM_OF_COLS - 1) { this.addButton.setDisable(true); this.addTextField.setDisable(true); this.enterCPUTimeLabel.setDisable(true); } if(!firstTimePressedAdd) { firstTimePressedAdd = true; this.startButton.setDisable(false); this.listOfProcesses = new LinkedList<>(); } currentCPUTimeRequestedInteger = Integer.parseInt(currentCPUTimeRequested); this.addTextField.setText(""); AddNewColToTable(currentCPUTimeRequestedInteger); }
关键说明
- 表格始终只保留一行空数据,所有新增列的单元格都会基于这一行渲染,不会出现行数增加的问题。
- 每个列的
ProgressIndicator是单元格专属的,独立于其他列,不会出现旧指示器被“推到新列”的情况。 - 如果需要让进度指示器跟随
Process的进度变化,只需在Process类中添加DoubleProperty类型的进度属性,然后在自定义单元格中绑定即可。
内容的提问来源于stack exchange,提问作者Yarin0600
相关产品推荐
相关产品推荐

