for循环执行完毕后Applet界面无内容显示的问题求助
正确的实现思路
我们需要把数据生成和绘制逻辑彻底分离:
- 用一个集合保存所有要绘制的弧的完整信息(位置、尺寸、颜色)
- 用独立的工作线程来生成弧的数据,每次生成后调用
repaint()触发UI重绘 paint()方法只负责遍历集合,把所有历史弧都重新绘制一遍,这样每次重绘都会保留之前的内容
修改后的完整代码
import java.applet.Applet; import java.awt.Color; import java.awt.Graphics; import java.util.ArrayList; import java.util.List; public class ColorArcs extends Applet { // 用内部类封装每个弧的所有绘制参数 private static class ArcInfo { int x, y, width, height; Color color; ArcInfo(int x, int y, int width, int height, Color color) { this.x = x; this.y = y; this.width = width; this.height = height; this.color = color; } } // 保存所有已生成的弧的信息 private final List<ArcInfo> arcs = new ArrayList<>(); private Thread drawingThread; // 控制线程运行的开关,volatile保证多线程可见性 private volatile boolean isRunning = false; @Override public void init() { // 初始化工作线程,负责生成弧的数据 drawingThread = new Thread(() -> { int currentWidth = 50; int currentLength = 50; isRunning = true; while (isRunning && currentLength < 250) { // 计算当前弧的位置 int arcX = 200 - currentLength / 2; int arcY = 200 - currentWidth / 2; // 确定当前弧的颜色 Color arcColor; if (currentLength >= 50 && currentLength < 75) { arcColor = Color.cyan; } else if (currentLength >= 75 && currentLength < 100) { arcColor = Color.yellow; } else if (currentLength >= 100 && currentLength < 125) { arcColor = Color.green; } else { arcColor = Color.red; } // 把当前弧的信息加入集合(加锁保证线程安全) synchronized (arcs) { arcs.add(new ArcInfo(arcX, arcY, currentLength, currentWidth, arcColor)); } // 更新下一个弧的参数 currentLength += 2; currentWidth++; // 等待80ms,这里在工作线程里不会阻塞UI try { Thread.sleep(80); } catch (InterruptedException e) { // 线程被中断时,终止循环 Thread.currentThread().interrupt(); isRunning = false; } // 触发UI重绘,通知系统调用paint() repaint(); } }); } @Override public void start() { // Applet启动时,启动工作线程 if (!drawingThread.isAlive()) { drawingThread.start(); } } @Override public void stop() { // Applet停止时,终止工作线程,避免资源泄漏 isRunning = false; drawingThread.interrupt(); } @Override public void paint(Graphics g) { // 遍历所有弧的信息,逐个绘制 synchronized (arcs) { for (ArcInfo arc : arcs) { g.setColor(arc.color); g.drawArc(arc.x, arc.y, arc.width, arc.height, 0, 180); } } } }
关键改动说明
- 数据持久化:用
ArcInfo类保存每个弧的所有参数,arcs集合存储历史数据,这样每次paint()都会重新绘制所有弧,不会丢失之前的内容。 - 独立工作线程:把循环和睡眠放到单独线程里,彻底避免阻塞UI线程,保证界面流畅响应。
- 线程安全:因为工作线程和UI线程都会访问
arcs集合,所以用synchronized块保证操作的原子性,避免并发问题。 - 正确设置颜色:直接给
Graphics对象设置颜色,而不是调用setForeground(),这样每个弧可以使用独立的颜色,不受组件全局前景色的影响。 - 生命周期管理:在
start()启动线程,stop()停止线程,符合Applet的生命周期规范,避免Applet退出后线程仍然运行导致的资源泄漏。
内容的提问来源于stack exchange,提问作者user8234870
相关产品推荐
相关产品推荐

