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

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);
            }
        }
    }
}

关键改动说明

  1. 数据持久化:用ArcInfo类保存每个弧的所有参数,arcs集合存储历史数据,这样每次paint()都会重新绘制所有弧,不会丢失之前的内容。
  2. 独立工作线程:把循环和睡眠放到单独线程里,彻底避免阻塞UI线程,保证界面流畅响应。
  3. 线程安全:因为工作线程和UI线程都会访问arcs集合,所以用synchronized块保证操作的原子性,避免并发问题。
  4. 正确设置颜色:直接给Graphics对象设置颜色,而不是调用setForeground(),这样每个弧可以使用独立的颜色,不受组件全局前景色的影响。
  5. 生命周期管理:在start()启动线程,stop()停止线程,符合Applet的生命周期规范,避免Applet退出后线程仍然运行导致的资源泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:53:47