无法获取JTable总宽度,如何按百分比设置其列宽?
解决JTable获取真实宽度并设置百分比列宽的问题
为什么getWidth()返回0?
Swing组件的实际尺寸是在布局管理器完成布局、组件被渲染到屏幕之后才确定的。你当前的代码在dialog.pack()和dialog.setVisible(true)之前调用getWidth(),这时候组件还处于“未布局”状态,宽度自然是0。
方案一:延迟到组件渲染后执行列宽设置
把列宽计算的代码放到dialog.setVisible(true)之后,或者用SwingUtilities.invokeLater()让代码在EDT(事件调度线程)上延迟执行,确保组件已经完成布局:
dialog.add(header,BorderLayout.NORTH); dialog.add(timeLineDialog,BorderLayout.CENTER); dialog.add(footer,BorderLayout.SOUTH); timeLineDialog.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); // 先关闭自动调整 dialog.pack(); dialog.setVisible(true); // 组件显示后再计算列宽 SwingUtilities.invokeLater(() -> { int panelSize = timeLineDialog.getWidth(); System.out.println("total width=" + panelSize); for (int i = 0; i < percentWidths.length; i++) { int columnWidth = (int) Math.round(panelSize * percentWidths[i]); System.out.println("setting column " + i + " to " + columnWidth); timeLineDialog.getColumnModel().getColumn(i).setPreferredWidth(columnWidth); } });
方案二:监听组件尺寸变化(更健壮,支持窗口 resize)
如果需要支持用户调整窗口大小时,列宽也能按百分比自适应,给JTable添加ComponentListener,监听尺寸变化事件:
dialog.add(header,BorderLayout.NORTH); dialog.add(timeLineDialog,BorderLayout.CENTER); dialog.add(footer,BorderLayout.SOUTH); timeLineDialog.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); // 添加尺寸监听 timeLineDialog.addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { int panelSize = timeLineDialog.getWidth(); if (panelSize <= 0) return; // 避免初始未布局的情况 for (int i = 0; i < percentWidths.length; i++) { int columnWidth = (int) Math.round(panelSize * percentWidths[i]); timeLineDialog.getColumnModel().getColumn(i).setPreferredWidth(columnWidth); } } }); dialog.pack(); dialog.setVisible(true);
注意事项
- 一定要先设置
JTable.AUTO_RESIZE_OFF,否则Swing的自动列宽调整会覆盖你设置的宽度。 - 如果
percentWidths数组的总和不是1.0,可能会导致列宽总和超过或不足表格宽度,建议确保百分比总和为100%(即数组元素和为1.0)。
内容的提问来源于stack exchange,提问作者Wt Riker
相关产品推荐
相关产品推荐

