如何创建响应式Java SWT多列表格(解决Section折叠宽度异常)
解决Eclipse FormView中Section展开折叠时表格列宽异常的问题
我来帮你搞定这个表格宽度异常的问题!先梳理下你代码里的小问题,再给你可靠的解决方案:
首先修正代码里的笔误
你在controlResized方法里把column1的宽度重复设置了两次,应该给column2分配第二列的宽度:
// 错误写法 column1.setWidth(width / 3); column1.setWidth(width * 2 / 3); // 正确写法 column1.setWidth(width / 3); column2.setWidth(width * 2 / 3);
另外还要注意变量名一致性:你创建表格用的是table,但创建列时写了testCaseTable,得统一成同一个变量。
核心问题:Section展开折叠时未触发正确的列宽计算
你当前只监听了Form的大小变化,但Section展开/折叠时,表格的可用空间变化并不会直接触发Form的controlResized事件,而且你获取的宽度也不是表格实际能使用的有效宽度。我们需要做两件关键调整:
- 监听Section的
Expand和Collapse事件,在Section状态变化时重新计算列宽 - 正确获取表格的可用宽度(排除边框、滚动条的占用空间)
修改后的完整代码示例
// 假设你的Section实例是section Section section = ...; // 替换成你实际的Section对象 // 创建表格的基础代码 Table table = new Table(parent, SWT.MULTI | SWT.H_SCROLL | SWT.BORDER); FormData fd = new FormData(); fd.height = 200; fd.top = new FormAttachment(removeTestCaseButton, 5); fd.left = new FormAttachment(1); fd.right = new FormAttachment(99); table.setLayoutData(fd); table.setLinesVisible(true); table.setHeaderVisible(true); // 创建表格列,修正变量名 TableColumn column1 = new TableColumn(table, SWT.CENTER); column1.setText("column One"); TableColumn column2 = new TableColumn(table, SWT.CENTER); column2.setText("column Two"); // 抽离统一的列宽计算逻辑,避免重复代码 Runnable resizeColumns = () -> { // 获取表格的实际可用客户端区域 Rectangle clientArea = table.getClientArea(); int availableWidth = clientArea.width; // 如果表格有水平滚动条,减去滚动条的宽度 if ((table.getStyle() & SWT.H_SCROLL) != 0) { availableWidth -= table.getHorizontalBar().getSize().y; } // 设置1:2的列宽比例 column1.setWidth(availableWidth / 3); column2.setWidth(availableWidth * 2 / 3); }; // 监听Form的大小变化 form.addControlListener(new ControlAdapter() { @Override public void controlResized(ControlEvent e) { resizeColumns.run(); } }); // 监听Section的展开/折叠事件 section.addListener(SWT.Expand, event -> resizeColumns.run()); section.addListener(SWT.Collapse, event -> resizeColumns.run()); // 初始化时调用一次,确保打开View时列宽正确 resizeColumns.run();
为什么这样有效?
- 把列宽计算逻辑抽成独立方法,保证所有需要调整列宽的场景都能复用,避免代码冗余
- 监听Section的状态变化事件,确保展开/折叠时立即重新计算列宽,适配新的可用空间
- 使用
table.getClientArea()获取表格实际能使用的宽度,再减去水平滚动条的占用空间,这样设置的列宽不会超出可视区域,不会出现多余的水平滚动条
内容的提问来源于stack exchange,提问作者Saji Liyanage
相关产品推荐
相关产品推荐

