アプレットのフレーム上でマウスを動かすと AWT イベントディスパッチスレッドから
java.lang.ClassCastException
が スローされる
症状Sun JavaTM Runtime Environment (JRETM) 実装を使ってブラウザ内でアプレットを実行しているときにアプレットのフレーム上でマウスを動かすと、次のコードに示すように、Abstract Window Toolkit (AWT) イベントディスパッチスレッドから
java.lang.ClassCastException
がスローされます。
java.lang.ClassCastException:sun.plugin....
at MyApplet.mouseExit(Unknown Source)
at java.awt.Component.handleEvent(Unknown Source)
at java.awt.Component.postEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)Microsoft Virtual Machine (VM) ではアプレットは何のエラーもなく実行されます。
原因
この例外には、考えられる原因が 2 つあります。
- アプレットはそのフレーム上でのマウスイベントを追跡するために、フレーム上の
MouseListener
イベントの登録を試みます。Microsoft VM の実装では、AWT 階層コンポーネントツリーアプレットにおけるアプレットの直接の親はフレームです。したがって、アプレットの中には、次のコードに依存しているものもあります。
public void foo()
{
Frame f = (Frame) getParent();
....
}
しかし、アプレットの直接の親は実装に固有であり、変わる可能性があります。Sun JRE ではアプレットとフレームの間にほかのコンテナが存在しているため、getParent()
メソッドからFrame
オブジェクトが返されず、上記コードの実行時にjava.lang.ClassCastException
エラーが発生します。
- Microsoft VM の実装では、
java.applet.AppletContext
インタフェースはアプレットのフレームで実装されています。したがって、アプレットの中には、次のコードに依存しているものもあります。public void foo()
{
Frame f = (Frame) getParent();
....
AppletContext ac = (AppletContext) f;
....
}しかし、アプレットの直接の親は実装に固有であり、変わる可能性があります。Sun JRE では別のオブジェクトを使用して
AppletContext
を実装しているため、上記のコードではjava.lang.ClassCastException
がスローされます。解決方法
原因が最初のものである場合、特定レベルのフレームに依存する代わりに、アプレットから AWT 階層コンポーネントツリーの全体をナビゲートしてフレームを特定します。次のコードでは、コンポーネントツリー全体のナビゲート方法を示します。
public void foo()
{
// Navigate component tree
Container c = getParent();
while (c != null && (c instanceof Frame) == false)
c = c.getParent();
// Cast Container to Frame
if (c instanceof Frame)
{
Frame f = (Frame) c;
...
}
}原因が 2 番目のものである場合、次のコードに示すように、
Applet.getAppletContext()
メソッドを使ってAppletContext
にアクセスします。
public void foo()
{
....
AppletContext ac = (AppletContext) getAppletContext();
...
}
詳細情報
なし。