Applet.start() または Applet.stop() が呼び出されると、java.lang.NullPointerException がスレッドからスローされる


症状

アプレットを Sun JRE を使用したブラウザで実行している場合、Applet.start() または Applet.stop() が呼び出されると、NullPointerException がスレッドからスローされます。同じアプレットが Microsoft VM では実行できます。

原因

Microsoft VM では、Applet.init() が呼び出されるとすぐ、Applet.start() が呼び出される前に、アプレットが可視状態になります。同様に、Applet.stop() の後で Applet.destroy() が呼び出されるまでは、アプレットは可視状態のままです。

ライフサイクルメソッドに関して、Sun JRE の実装ではわずかですが、アプレットの可視性について異なります。そのため、Microsoft VM イベントシーケンスを前提としたアプレットはすべて停止する可能性があります。

解決方法

アプレットが描画前に可視状態になるように対策を講じたコードを記述します。その 1 つに、Graphics オブジェクトが null かどうかをテストする方法があります。たとえば、アプレットに次のメソッドが含まれているとします。

        private Thread paintThread = null;

        public void start()
        {
               if (paintThread == null)
                {
                    paintThread = new Thread(this);
                   paintThread.start();           
                }   
        }

        public void stop()
        {
               if (paintThread != null)
                {
                    paintThread.interrupt();    // Assuming the thread has sufficient                                       // time to be interrupted and stop                                       // drawing before destroy() is called.
                    paintThread = null;
                }
        }

        public void run()
        {
                while (Thread.currentThread().isInterrupted() == false)
                {
                        Graphics g = getGraphics();                   
                        g.drawString("Hello World", 100, 100);   // NullPointerException if                                                      // applet is not visible -
                                                     //
g will be null !
                }
        }

       run メソッドのコードを次のように変更します。

        public void run()
        {
                while (Thread.currentThread().isInterrupted() == false)
                {
                        Graphics g = getGraphics();                 

                        if (g != null)               // Code defensively!
                            g.drawString("Hello World", 100, 100);  
                }
        }

詳細情報

        なし