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

SWT表格批量移除Button单元格问题求助

SWT Table批量移除按钮组件及获取按钮行索引解决方案

你遇到的核心问题是没有维护每行按钮和TableEditor的引用集合——当前你把operationButtons、removeButtons、checkButtons定义为单个变量,每次添加新行时都会覆盖之前的引用,导致Remove All时只能处理最后一行的组件。下面针对你的两个需求给出具体解决方案:


1. 批量移除所有Button和TableEditor组件

最可靠的方式是自己维护每行创建的按钮和编辑器引用,这样批量操作时可以精准遍历处理:

步骤1:定义集合存储组件引用

在Test类中添加几个集合,用来保存所有行的按钮和TableEditor:

private List<Button> allCheckButtons = new ArrayList<>();
private List<Button> allRemoveButtons = new ArrayList<>();
private List<Button> allOperationButtons = new ArrayList<>();
private List<TableEditor> allTableEditors = new ArrayList<>();

步骤2:添加行时将组件存入集合

在dateReceived方法中,创建每个按钮和TableEditor后,立即添加到对应集合:

// 创建复选框按钮并加入集合
checkButtons = new Button(table, SWT.CHECK);
allCheckButtons.add(checkButtons);

// 创建移除按钮并加入集合
removeButtons = new Button(table, SWT.PUSH);
allRemoveButtons.add(removeButtons);

// 创建操作按钮并加入集合
operationButtons = new Button(table, SWT.PUSH);
allOperationButtons.add(operationButtons);

// 将三个TableEditor加入集合
allTableEditors.add(checkEditors);
allTableEditors.add(removeEditors);
allTableEditors.add(operationEditors);

步骤3:Remove All时批量销毁组件

修改Remove All按钮的监听器,遍历集合销毁所有组件并清空集合,最后清除表格行:

button.addListener(SWT.Selection, new Listener() {
    @Override
    public void handleEvent(Event e) {
        // 销毁所有按钮(先判断是否已销毁,避免异常)
        for (Button btn : allCheckButtons) {
            if (!btn.isDisposed()) btn.dispose();
        }
        for (Button btn : allRemoveButtons) {
            if (!btn.isDisposed()) btn.dispose();
        }
        for (Button btn : allOperationButtons) {
            if (!btn.isDisposed()) btn.dispose();
        }

        // 销毁所有TableEditor
        for (TableEditor editor : allTableEditors) {
            editor.dispose();
        }

        // 清空集合,避免内存泄漏
        allCheckButtons.clear();
        allRemoveButtons.clear();
        allOperationButtons.clear();
        allTableEditors.clear();

        // 清除表格行数据
        table.removeAll();

        // 重新布局组件
        composite.layout(true, true);
    }
});

这种方式比遍历table.getChildren()更精准,不会误删表格内的其他控件,也能确保所有组件都被正确销毁。


2. 获取每个Button所在行的索引

可以通过SWT控件的setData()和getData()方法,将按钮与对应的TableItem或行索引关联起来,具体有两种方式:

方式一:关联TableItem(推荐)

在创建按钮时,把对应的TableItem存入按钮的自定义数据中:

// 在dateReceived方法中创建removeButtons后添加
removeButtons.setData("tableItem", item);

然后在按钮的Selection监听器中,取出TableItem并获取当前行索引:

removeButtons.addListener(SWT.Selection, new Listener() {
    @Override
    public void handleEvent(Event e) {
        Button currentBtn = (Button) e.widget;
        // 获取关联的TableItem
        TableItem item = (TableItem) currentBtn.getData("tableItem");
        // 获取当前行索引(实时更新,不受行删除影响)
        int rowIndex = table.indexOf(item);
        
        // 后续业务逻辑...
        MessageBox messageBox = new MessageBox(composite.getShell(), SWT.ICON_QUESTION | SWT.YES | SWT.NO);
        messageBox.setMessage("Do you really want to remove row " + rowIndex + "?");
        // ...
    }
});

这种方式的优势是,即使表格行被删除或顺序变化,table.indexOf(item)也能获取到当前最新的行索引。

方式二:直接存储行索引

如果不需要实时索引,也可以在创建行时直接把索引存入按钮:

// 在dateReceived方法中创建按钮后
int currentRowIndex = table.indexOf(item);
removeButtons.setData("rowIndex", currentRowIndex);

然后在监听器中直接取出:

int rowIndex = (int) currentBtn.getData("rowIndex");

注意:这种方式的索引是创建行时的初始索引,如果后续有行被删除,这个索引会和实际行位置不符,所以更推荐方式一。


内容的提问来源于stack exchange,提问作者krezus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:00:27