Java 面向对象 · 交互课程

Applet 小程序(legacy·历史了解)

Applet 小程序(legacy·历史了解)

目标:理解 Applet 的基本工作原理与「容器」概念;掌握 Applet 类与生命周期方法 init/start/stop/destroy 的调用顺序;会用 getParameter 读取参数。明确标注:现代 Java 已弃用浏览器插件,本节仅作历史了解——重点在容器思想,它在新容器中依然成立。

一、什么是 Applet 与「容器」概念

思政:容器是平台。个人借助平台提升能力,同时必须遵章守纪(容器的安全边界)、有团队合作意识(程序与容器各司其职)。

二、Applet 类与生命周期

java.applet.Applet 继承自 Panel,定义了四个由容器调用的生命周期方法:

public class EraseGameApplet extends Applet implements KeyListener {
    public void init()      { setSize(645,560); addKeyListener(this); setFocusable(true); } // 一次
    public void start()     { box[0].pause=false; box[1].pause=false; }                     // 可多次
    public void stop()      { box[0].pause=true;  box[1].pause=true;  }                     // 可多次
    // destroy():释放资源,一次(本例用默认实现)
}

调用顺序:容器加载 → init()(一次)→ start();窗口失焦/切走 → stop(),重新聚焦 → 再 start()(start ⇄ stop 可交替多次);关闭页面 → destroy()(一次,之后结束)。对照课件中的 AWTAppletViewer:它在 windowActivated 里调 applet.start()、windowDeactivated 里调 applet.stop()——生命周期完全由容器驱动。

交互实验:Applet 生命周期(AppletLifecycleMachine)

legacy · 历史了解

以 EraseGameApplet 为例:点下面的「容器事件」按钮,看容器按什么顺序调用 init / start / stop / destroy。 start ⇄ stop 可以交替多次;destroy 之后一切结束。

已加载
→
已初始化
→
运行中
⇄
已暂停
→
已销毁

当前:已加载 —— 容器下载并实例化 Applet 对象,尚未调用任何生命周期方法

容器调用日志

  1. 对象已加载,等待容器调用 init()

四个生命周期方法(对照 EraseGameApplet.java)

方法调用次数本例做了什么
init()一次setSize(645,560)、addKeyListener(this)、setFocusable(true)——只做一次
start()可多次box[0].pause=false; box[1].pause=false——恢复两个游戏盒,可多次调用
stop()可多次box[0].pause=true; box[1].pause=true——暂停两个游戏盒,可多次调用
destroy()一次释放资源(本例默认实现为空)——只做一次,之后对象不再被使用

Applet 是历史技术:现代浏览器已移除 Java 插件(NPAPI),JDK 17 起 java.applet 包被正式弃用(deprecated)。本页仅作历史了解——重点是理解「容器」概念与生命周期模型,这套思想在 HTML5、小程序等新容器中依然成立。

交互实验:生命周期时间线(AppletLifecycleTimeline)

逐个触发容器事件,看 SVG 时间线上标记如何累积:浏览器前进/后退 = 失焦+聚焦 = stop→start 循环;destroy 之后一切不可逆。

loaded0
当前状态:loadedstop→start 循环次数:0

事件明细

  1. t=0对象已加载

对照 EraseGameApplet:stop() 把两个游戏盒 pause=true,start() 恢复 pause=false——每次浏览器前进/后退都是一对 stop+start, 而 destroy() 只执行一次,之后对象不再被使用。

三、参数传递

HTML 中用 <applet> 标签嵌入,并用 <param> 传参:

<applet code="EraseGameApplet.class" width="645" height="560">
  <param name="speed" value="fast">
</applet>

Applet 里用 getParameter("speed") 读取(返回 String,无此参数返回 null)。容器把外部配置交给程序——这正是「容器提供运行时资源」的体现。

四、容器对比:EraseGameApp vs EraseGameApplet

同一款 ERASE 游戏(素材 Erase-JAVA/ 与 Erase-JAVA-Applet/),一个写成应用、一个写成 Applet,体会「容器内编程」的便利与限制:

方面EraseGameApp(应用版)EraseGameApplet(Applet 版)
入口有 main():自己 new、自己开窗口没有 main():由容器加载并 new
生命周期程序自己管理窗口开关init/start/stop/destroy 由容器按页面与焦点状态调用
运行环境本机 JVM,直接访问本地资源浏览器沙箱内,本地资源访问受限
部署方式分发 .class/.jar + bat 运行上传服务器,HTML 一个 <applet> 标签到处跑
跨平台依赖每台机器装 JVM容器屏蔽平台差异,「一次编写,到处运行」

五、为什么过时了?新容器是什么

思考题

  1. init()/start()/stop()/destroy() 各被容器调用几次?为什么 start/stop 可以交替多次?
  2. Applet 与 Swing 应用(有 main)在「谁管理生命周期」上有何本质区别?
  3. 「容器提供资源 + 划定边界」的思想,在微信小程序里如何体现?

学习小测验

学习小测验

Q1

Applet 程序( )

Q2

Applet 生命周期中只执行一次的方法是( )

Q3

用户切到别的标签页再切回来,容器依次调用的方法是( )

Q4

Applet 中读取 HTML <param> 传进来的参数用( )

Q5

「容器」概念的核心价值是( )

Q6

Applet 如今被弃用(legacy)的主要原因是( )