Solved

Assigning appletContext to an applet

Posted on 1998-11-25
7
319 Views
Last Modified: 2013-11-23
I have been working on making an applet that runs other applets.  Everything works with most applets, but an applet which uses the getGraphics() method returns a null pointer exception.  I believe, as someone suggested, I just need to assign the parent appletContext to the instance of the applet, but for some reason I have not been able to get that to work.  This is essentially the part of the code I use to instantiate and run an applet:
  the_frame = new Frame();
  the_app.init();
  the_frame.add(the_app);
  the_frame.setSize(width,height);
  the_frame.show();
  the_app.start();
Exactly how can I can assign appletContext to this, and do I need to do any extra implements, import, or extends commands for my class?  Will this allow me to use getGraphics() with the applets it runs?

Thanks a lot.
0
Comment
Question by:cms6204
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 
LVL 5

Accepted Solution

by:
msmolyak earned 70 total points
ID: 1228203
To get an applet context you call applet.getAppletContext(). Thus if you override this method of your applet class you will allow interested parties to get a hold of applet's context.Solving th eproblem with getGraphics depends upon whether it uses the applet context and if yes, then how. To figure that out create a class MyAppletContext which implements AppletContext. Each method of that class will print its name (besides doing something useful). Override the getAppletContext() method of your subclass of Applet class to return an instance of MyAppletContext class. When you call getGraphics() you will know if any of the method of your applet context are used by the presence or abcense of printed information.
0
 
LVL 16

Expert Comment

by:heyhey_
ID: 1228204
"getGraphics returns null" is probably because applet peer is not created / initialized at the moment (so your applet don't have associated Graphics object). you probably must create Applet, add it to Frame, show it (peers are created) and then call its init method ... (just a quick suggestion)
0
 
LVL 16

Expert Comment

by:heyhey_
ID: 1228205
and when exactly getGraphics() returns null. Give us the stacktrace (+ the source code of the "bad applet")

0
Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

 

Author Comment

by:cms6204
ID: 1228206
Here is the method which runs the applets.  In the real version, the applets are in a linked list so that we can intercept each one's windowClosing message and destroy them when the user clicks on the close box (multiple applets can be run at once), but I have made it simpler here.  As it is coded below, it correctly runs any applet (that we have tested) that does not call getGraphics(), but when an applet does call getGraphics(), it gives the following errors (Bouncing_Ball2 code is at end of this comment):
  java.lang.NullPointerException
     at Ball.draw_ball(Bouncing_Ball2.java:101)
     at Ball.bounce(Bouncing_Ball2.java:109)
     at Bouncing_Ball2.star(Bouncing_Ball2.java:21)              atAppletViewDynamicBeta2.runApp                                         (AppletViewDynamicBeta2.java:332)
     at AppletViewDynamicBeta2.actionPerformed(Compiled Code)
as well as errors in java.awt

  public void runApp(){
      boolean appletFound=true;
      Applet app = new Applet();
      try {
        Class c = Class.forName(app_to_run);
        app = (Applet) Class.forName(app_to_run).newInstance();
      } // end of try
      // if no applet class can be instantiated, assign an error
      // message and return to user-input paint method
      catch (Exception e) {
        error = "No applet with this name found.";
        appletFound=false;
        repaint();
      } // end of catch
      if (appletFound) {
        Frame fr=new Frame();
        app.init();
        fr.add(app);
        fr.setSize(width,height);
        fr.show();
        app.start();
      } // end of if
      // be processed
  } // end of runApp()

If I move the app.init() line to between fr.show() and app.start(), it gives no errors with either program, but components, such as buttons and textfields, will either not appear or not work.  Thanks a lot for your help.  If you can help, I may accept msmolyak's answer, but I can post a "dummie" question for you so you can get some points for your efforts.  Here is Bouncing_Ball2 (it is threaded):

import java.applet.Applet;
import java.awt.*;

public class Bouncing_Ball2 extends Applet {
  private final int SIZE = 300;
  private Ball ball = new Ball(150, 10, 250, 200);
  private Graphics page;
  private Control_Panel controls;
  public void init() {
    setVisible(true);
    setSize(SIZE,SIZE);
    page = getGraphics();
    page.setXORMode(getBackground());
  }
  public void start() {
    controls = new Control_Panel(Thread.currentThread());
    controls.start();
    ball.pause();
    while(ball.moving()) {
      ball.bounce(page);
    }
  }
}

class Control_Panel extends Thread {
  private Button suspend = new Button("suspend");
  private Button resume = new Button("resume");
  private Frame frame = new Frame("Bouncing Ball Control Panel");
  private Thread applet_thread;
  Control_Panel(Thread applet_thread) {
    this.applet_thread = applet_thread;
  }
  public void run() {
    Resume_Action resume_action = new Resume_Action(applet_thread);
    Suspend_Action suspend_action = new Suspend_Action(applet_thread);
    suspend.addActionListener(suspend_action);
    resume.addActionListener(resume_action);
    frame.setLayout(new FlowLayout());
    frame.add(suspend);
    frame.add(resume);
    frame.pack();
    frame.setLocation(250, 200);
    frame.setVisible(true);
  }
}

class Suspend_Action implements ActionListener {
  Thread applet_thread;
  Suspend_Action(Thread applet_thread) {
    this.applet_thread = applet_thread;
  }
  public void actionPerformed(ActionEvent action) {
    applet_thread.suspend();
  }
}

class Resume_Action implements ActionListener {
  Thread applet_thread;
  Resume_Action(Thread applet_thread) {
    this.applet_thread = applet_thread;
  }
  public void actionPerformed(ActionEvent action) {
    applet_thread.resume();
  }
}

class Ball {
  private final int MOVE = 2;
  private final float DISTANCE = 0.97f;
  private final int SIZE = 20;
  private final int PAUSE = 5;
  private int x;
  private int start_y;
  private int end_y;
  private int length;
  private boolean moving_up = true;
  Ball(int new_x, int new_start_y, int new_end_y, int new_length) {
    x = new_x;
    start_y = new_start_y;
    end_y = new_end_y;
    length = new_length;
  }
  public void pause() {
    try {
      Thread.currentThread().sleep(PAUSE);
    }
    catch (InterruptedException exception) {
      System.out.println("have an exception");
    }
  }
  void move() {
    if (moving_up) {
      end_y = end_y - MOVE;
    }
    else {
      end_y = end_y + MOVE;
    }
  }
  void draw_ball (Graphics page) {
    page.drawOval (x-(SIZE/2), end_y, SIZE, SIZE);
    page.drawLine (x, start_y, x, end_y);
  }
  public boolean moving() {
    return length != 0;
  }
  public void bounce(Graphics page) {
    for (int count = 1; count < length; count+=MOVE) {
      draw_ball(page);
      pause();
      draw_ball(page);
      move();
    }
    moving_up = !moving_up;
    length = (int) (DISTANCE * length);
  }
}




0
 
LVL 16

Expert Comment

by:heyhey_
ID: 1228207

 /*
the real answer is - you don't have problems with the "visualizator" applet,
but with applets that use getGraphics, because THEY DON'T BEHAVE properly !!!
so this is not an AppletContext problem, but a Graphics one.
*/

/*
getGraphics is a pretty tricky method and applets (and all other java components) are not supposed to use it at all
(you can search through java.* sources and see that NOBODY, NOWHERE uses this method directly !!!)

applets are supposed to draw themselves only in their update / paint methods (and there they receive the appropriate Graphics object as method invocation parameter)

i think that
- (for your own applets) you should always NOT use getGraphics. you should make the appropriate change, call repaint and
JVM will call your paint method with the appropriate Graphics object.
- (for your own applets) you should always use SAFE coding - for example

public void paint(Graphics g)
{
      if (g == null) return; // paranoia :)
      if (img == null) return; // safe !!
      g.drawImage(img);
}

- using getGraphics() will probably bring many refresh problems. for example suspend your ball, and bring some other Frame in front of the applet window. when you move this window, Ball will not repaint itself !!!

- from the docs
 public void paint(Graphics g)
    Paints this component. This method is called when the contents of the component should be
    painted in response to the component first being shown or damage needing repair. The clip
    rectangle in the Graphics parameter will be set to the area which needs to be painted.

 public Graphics getGraphics()
    Creates a graphics context for this component. This method will return null if this component
    is currently not on the screen.

so you will receive graphics object only after you've already showed your component
(that is - when the native peer is already created)

look at the source of getGraphics method

     public Graphics getGraphics() {
      if (peer instanceof java.awt.peer.LightweightPeer) {
          // This is for a lightweight component, need to
          // translate coordinate spaces and clip relative
          // to the parent.
          Graphics g = parent.getGraphics();
          g.translate(x,y);
          g.setClip(0, 0, width, height);
            g.setFont(getFont());
          return g;
      } else {
          ComponentPeer peer = this.peer;
          return (peer != null) ? peer.getGraphics() : null;
      }
    }

Summary:
1.) never use .getGraphics method and never KEEP the returned Graphics object !!! (this is a really bad practice)
2.) if you really need this to work with this "VERY BAD behaved applet", you certainty need to call the fr.show()
method before app.init() method (so that all the peer objects are created and you have the peer Graphics)
3.) i'm posting modified version of the applet code that paints itself only in its paint method. it works in appletviewer and it should work in your frame too

hope this helps
  heyhey
 */

import java.applet.Applet;
 import java.awt.*;
 import java.awt.event.*;

 public class Bouncing_Ball2 extends Applet {
   private final int SIZE = 300;
   private Ball ball = new Ball(150, 10, 250, 200);
//   private Graphics page;
   private Control_Panel controls;
   public void init() {
     setVisible(true);
     setSize(SIZE,SIZE);
//     page = getGraphics();
//     page.setXORMode(getBackground());
   }

   public void paint(Graphics g) {

     //controls = new Control_Panel(Thread.currentThread());
       ball.draw_ball(g);


       }


   public void start() {
     controls = new Control_Panel(Thread.currentThread());
     controls.start();
     ball.pause();
     while(ball.moving()) {
       ball.bounce();
     }
   }

 class Control_Panel extends Thread {
   private Button suspend = new Button("suspend");
   private Button resume = new Button("resume");
   private Frame frame = new Frame("Bouncing Ball Control Panel");
   private Thread applet_thread;
   Control_Panel(Thread applet_thread) {
     this.applet_thread = applet_thread;
   }
   public void run() {
     Resume_Action resume_action = new Resume_Action(applet_thread);
     Suspend_Action suspend_action = new Suspend_Action(applet_thread);
     suspend.addActionListener(suspend_action);
     resume.addActionListener(resume_action);
     frame.setLayout(new FlowLayout());
     frame.add(suspend);
     frame.add(resume);
     frame.pack();
     frame.setLocation(250, 200);
     frame.setVisible(true);
   }
 }

 class Suspend_Action implements ActionListener {
   Thread applet_thread;
   Suspend_Action(Thread applet_thread) {
     this.applet_thread = applet_thread;
   }
   public void actionPerformed(ActionEvent action) {
     applet_thread.suspend();
   }
 }

 class Resume_Action implements ActionListener {
   Thread applet_thread;
   Resume_Action(Thread applet_thread) {
     this.applet_thread = applet_thread;
   }
   public void actionPerformed(ActionEvent action) {
     applet_thread.resume();
   }
 }

 class Ball {
   private final int MOVE = 2;
   private final float DISTANCE = 0.97f;
   private final int SIZE = 20;
   private final int PAUSE = 5;
   private int x;
   private int start_y;
   private int end_y;
   private int length;
   private boolean moving_up = true;
   Ball(int new_x, int new_start_y, int new_end_y, int new_length) {
     x = new_x;
     start_y = new_start_y;
     end_y = new_end_y;
     length = new_length;
   }
   public void pause() {
     try {
       Thread.currentThread().sleep(PAUSE);
     }
     catch (InterruptedException exception) {
       System.out.println("have an exception");
     }
   }
   void move() {
     if (moving_up) {
       end_y = end_y - MOVE;
     }
     else {
       end_y = end_y + MOVE;
     }
   }
   void draw_ball (Graphics page) {
     page.drawOval (x-(SIZE/2), end_y, SIZE, SIZE);
     page.drawLine (x, start_y, x, end_y);
   }
   public boolean moving() {
     return length != 0;
   }
   public void bounce() {
     for (int count = 1; count < length; count+=MOVE) {
       //draw_ball(page);
         repaint();
       pause();
       //draw_ball(page);
         repaint();
       move();
     }
     moving_up = !moving_up;
     length = (int) (DISTANCE * length);
   }
 }
 }

0
 

Author Comment

by:cms6204
ID: 1228208
Thanks for your help heyhey_;  I think I have everything working the way it needs to now.  I'm posting another "dummie" question for you to answer so I can give you some of the points you deserve for helping me with your comments on this one.  It's titled "AppletViewer (for heyhey_)".  
0
 

Author Comment

by:cms6204
ID: 1228209
msmolyak, sorry it took me so long to respond;  I wanted to keep my question active for a while because I also got a lot of valuable help from someone else's comments.  I think I have everything working as it needs to now.  Thanks.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Oracle SQL syntax check  without executing 6 108
mysql jsp example issue 32 75
junit as external jar or library 7 40
Java class and jar 3 43
For beginner Java programmers or at least those new to the Eclipse IDE, the following tutorial will show some (four) ways in which you can import your Java projects to your Eclipse workbench. Introduction While learning Java can be done with…
Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Viewers learn about the scanner class in this video and are introduced to receiving user input for their programs. Additionally, objects, conditional statements, and loops are used to help reinforce the concepts. Introduce Scanner class: Importing…
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question