《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
相关产品推荐
相关产品推荐

