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

《Thinking in Java》中ColorBox程序因run()方法问题无法运行求助

解决ColorBoxes程序中缺少run()方法导致的异常问题

嗨,我看你在运行《Thinking in Java》里的ColorBoxes程序时遇到了找不到run()方法的异常,这个问题很明确——原代码里的run(boxes, 500,400)是给JApplet版本用的启动方法,但你现在的代码是基于JFrame的桌面应用,根本没有对应的实现,而且那个错误的sun.misc.PostVMInitHook.run导入也完全帮不上忙。

下面是修复后的完整代码,我已经把问题部分替换成了JFrame桌面应用的标准启动逻辑:

import javax.swing.*;
import java.awt.*;
import java.util.concurrent.*;
import java.util.*;

class CBox extends JPanel implements Runnable {
    private int pause;
    private static Random rand = new Random();
    private Color color = new Color(0);

    public void paintComponent(Graphics g) {
        g.setColor(color);
        Dimension s = getSize();
        g.fillRect(0, 0, s.width, s.height);
    }

    public CBox(int pause) {
        this.pause = pause;
    }

    public void run() {
        try {
            while (!Thread.interrupted()) {
                color = new Color(rand.nextInt(0xFFFFFF));
                repaint(); // 异步请求重绘
                TimeUnit.MILLISECONDS.sleep(pause);
            }
        } catch (InterruptedException e) {
            // 正常退出线程,无需额外处理
        }
    }
}

public class ColorBoxes extends JFrame {
    private int grid = 12;
    private int pause = 50;
    private static ExecutorService exec = Executors.newCachedThreadPool();

    public void setUp() {
        setLayout(new GridLayout(grid, grid));
        for (int i = 0; i < grid * grid; i++) {
            CBox cb = new CBox(pause);
            add(cb);
            exec.execute(cb);
        }
    }

    public static void main(String[] args) {
        ColorBoxes boxes = new ColorBoxes();
        if (args.length > 0)
            boxes.grid = Integer.parseInt(args[0]); // 优化Integer创建方式,避免过时方法
        if (args.length > 1)
            boxes.pause = Integer.parseInt(args[1]);
        boxes.setUp();

        // 替换原来错误的run()调用,改用JFrame标准启动流程
        boxes.setSize(500, 400);
        boxes.setTitle("Dynamic Color Boxes");
        boxes.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        // 窗口关闭时终止线程池,避免后台线程残留
        boxes.addWindowListener(new java.awt.event.WindowAdapter() {
            @Override
            public void windowClosing(java.awt.event.WindowEvent e) {
                exec.shutdownNow();
                System.exit(0);
            }
        });
        
        boxes.setVisible(true);
    }
}

关键修改说明:

  • 删掉无用导入:移除了import static sun.misc.PostVMInitHook.run;,这个导入和你需要的启动方法完全无关,只会造成混淆。
  • 替换启动逻辑:把原来的run(boxes, 500,400)换成了JFrame的标准配置:
    • setSize(500,400):设置窗口的宽高,对应原run方法的参数。
    • setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE):保证关闭窗口时整个程序正常退出,而不是留在后台。
    • setVisible(true):让窗口显示出来,这是桌面GUI程序必须的一步。
  • 优化线程管理:添加了WindowListener,在窗口关闭时调用exec.shutdownNow()中断所有CBox线程,避免程序退出后还有后台线程在运行。
  • 小优化:把new Integer(args[0])改成了Integer.parseInt(args[0]),避免使用过时的构造方法。

为什么原来的run方法不适用?

原来的JApplet版本的run方法是专门为小程序设计的,它负责把小程序嵌入到浏览器或小程序查看器中。但你的程序是桌面应用,用的是JFrame,完全不需要这套逻辑,直接配置窗口属性并显示就可以正常运行了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:00:20