遍历HashMap时getWidth()失效及GObjects添加失败问题求助
问题分析与修复方案
1. 循环内columnWidth为0的原因及解决
原因
当update方法在组件尚未完成布局时被调用(比如在组件添加到窗口前就调用addEntry),getWidth()和getHeight()会返回0,导致columnWidth = 0 / NDECADES = 0。你看到前面循环输出正常,是因为后续组件完成布局后,componentResized触发了第二次update,此时width值正常,但你可能误将第一次的输出当成了第二次的结果。
解决
在update方法开头添加判断,仅当组件宽高有效时执行绘图逻辑:
public void update() { // 组件未完成布局时直接返回,避免无效计算与绘图 if (getWidth() <= 0 || getHeight() <= 0) { return; } removeAll(); double canvasHeight = getHeight(); double canvasWidth = getWidth(); double columnWidth = canvasWidth / NDECADES; // 后续原有绘图代码... }
同时确保在组件添加到窗口并完成布局后,再调用addEntry或手动触发一次update。
2. GOval无法显示的原因及解决
原因
你的GOval存在两个明显问题:
- 当
i=0时,GOval(0,0,0,0)的宽高均为0,完全不可见; - 未结合你定义的
GRAPH_MARGIN_SIZE约束位置,导致部分GOval可能被边缘线条遮挡,或超出有效绘图区域。
解决
调整GOval的位置与大小,基于有效绘图区域计算:
for (ItemEntry entry : entries.values()) { String gName = entry.getName(); System.out.println(columnWidth); // 现在会输出正确值 // 计算有效绘图区域的边界 double topY = GRAPH_MARGIN_SIZE; double bottomY = canvasHeight - GRAPH_MARGIN_SIZE; for (int i = 0; i < NDECADES; i++) { // 让oval在对应列居中,且处于有效绘图区域内 double x = i * columnWidth + columnWidth / 2 - 5; // 5是oval半径,保证居中 double y = topY + (bottomY - topY) / 2 - 5; // 固定宽高为10x10,避免i=0时尺寸为0 GOval oval = new GOval(x, y, 10, 10); oval.setFilled(true); // 填充颜色,提升可见性 add(oval); } }
额外注意事项
- 所有Swing组件的UI操作必须在**事件调度线程(EDT)**中执行。如果你的
addEntry或文件读取操作在非EDT线程中调用,需用SwingUtilities.invokeLater包裹:SwingUtilities.invokeLater(() -> { itemGraph.addEntry(entry); }); - 确保
NDECADES、GRAPH_MARGIN_SIZE等常量被正确定义,避免出现除以0的异常(比如NDECADES为0会直接导致columnWidth异常)。
内容的提问来源于stack exchange,提问作者Vasyl F
相关产品推荐
相关产品推荐

