You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX如何给TableView单行新增列并添加ProgressIndicator

解决方案

问题根源

你的代码存在两个核心问题:

  1. 每次点击「Add」时都向tableOfProcesses.getItems()中添加新的Process对象,导致表格行数不断增加,违背了「始终仅保留一行」的需求。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 09:21:35