Question

I have an JApplet which during "init" starts JFrame. There are some operations in that JFrame and user closes the JFrame finally.

Now I'd like to notify the browser via javascript that something is to be done.

How to accomplish that? If it was the applet alone, the simple function below would be good enough

public void notifyBrowser() {
 JSObject browserWindow = JSObject.getWindow(this);
 browserWindow.eval("try{RefreshFilesInLongue();}catch(e){alert('error');}");
}

but "this" in the code is referring to the applet object, and I don't know how to reach that object while I am in the JFrame.

JFrame is called like below in order to receive focus:

public void init() {
 paramPostUrl = this.getParameter("postUrl");

/* Create and display the applet */
try {
    java.awt.EventQueue.invokeAndWait(new Runnable() {
    public void run() {
        initComponents();

        ScanFrame scanFrame = new ScanFrame();
        scanFrame.setPostUrl(paramPostUrl);
        scanFrame.setVisible(true);
        try {
        Thread.sleep(300L);
        scanFrame.toFront();
        } catch (InterruptedException ex) {
        Logger.getLogger(Applet.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    });
} catch (Exception ex) {
    ex.printStackTrace();
}
}

So my questions are:
1. how can I call notifyBrowser(), while being in scanFrame object
2. or how to detect that scanFrame was closed and being in applet object successfully call notifyBrowser?

Thanks for your help.


So modified code is like that:

public class Applet extends javax.swing.JApplet {
...
public void init() {
paramPostUrl = this.getParameter("postUrl");
myApplet = this;

/* Create and display the applet */
try {
    java.awt.EventQueue.invokeAndWait(new Runnable() {
    @Override
    public void run() {
        initComponents();
        ScanFrame scanFrame = new ScanFrame(myApplet);
...

and ScanFrame

public class ScanFrame extends javax.swing.JFrame implements ScannerListener {
 ...
 private JApplet appletObj;

 public ScanFrame(JApplet myApplet) {
appletObj = myApplet;
 ....

private void sendScannedDocumentToCallingApp() {
 ....
  JSObject browserWindow;
  browserWindow = JSObject.getWindow((JApplet)appletObj);
  browserWindow.eval("try{RefreshFilesInLongue();}catch(e){alert('error');}");
 }

and the error I get:

Exception in thread "AWT-EventQueue-2" java.util.NoSuchElementException
    at java.util.LinkedList.getFirst(Unknown Source)
    at java.awt.SequencedEvent.getFirst(Unknown Source)
    at java.awt.SequencedEvent.dispatch(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
Was it helpful?

Solution

  • If you need to open a separate window, don't use a JFrame. Use a modal JDialog, and then control returns automatically to the calling code.
  • If you need to pass the JApplet's reference into another class, simply pass it in as a parameter of the constructor.

i.e.,

ScanFrame scanFrame = new ScanFrame(this); 

where this represents the JApplet.

Note that calling Thread.sleep(300L); on the Swing event thread is a very bad idea. If you need a delay like this, use a Swing Timer so you don't shut down the event thread during the sleep.


Edit
You state,

I just copied some stuff I found in the Internet,

Be careful here. Copy ideas but not code lest you run into unseen walls.

...but I suspected it was not the way to go, although I didn't notify any problems with that until now and it solved the issue of the JFrame going behind the browser window. But the question is, when I pass the applet object via this, how can I call it and my function notifyBrowser. My Netbeans told me to change ScanFrame constructor to something like this: public ScanFrame(Runnable aThis)

Your JApplet class apparently implements Runnable but it also should extend JApplet. Note that the NetBeans suggestion is done out of ignorance of your plans. An IDE is smart, but only so smart. You know better that the constructor parameter should be a JApplet so that you can call JApplet methods on the parameter.

public class ScanFrame {
   private JApplet myApplet;

   public ScanFrame(JApplet myApplet) {
     this.myApplet = myApplet;
     // .... etc...
   }
}

and now you can call applet methods on the myApplet field.


Edit 2
Ah, my bad, I forgot that you were calling the constructor from an anonymous inner class. Let me change some recommendations:

  • First rename your class. "Applet" is already a name for a core Java class of some importance, and you don't want to use it as you may confuse others or yourself by doing this. Let's say you rename it to ScanFrameApplet.
  • Then to get the this of the instance of this applet inside of an anonymous inner class, you must preface the this with the class name, so in my instance it would be ScanFrameApplet.this.

i.e.,

public class ScanFrameApplet extends JApplet {
  try {
    java.awt.EventQueue.invokeAndWait(new Runnable() {
    @Override
    public void run() {
        initComponents();
        ScanFrame scanFrame = new ScanFrame(ScanFrameApplet.this);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top