1

我有一个 JApplet,它在“init”期间启动 JFrame。该JFrame中有一些操作,用户最终关闭了JFrame。

现在我想通过 javascript 通知浏览器有什么事情要做。

如何做到这一点?如果只是小程序的话,下面这个简单的功能就足够了

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

但是代码中的“this”指的是小程序对象,当我在 JFrame 中时,我不知道如何访问该对象。

为了获得焦点,JFrame 被调用如下:

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();
}
}

所以我的问题是:
1. 如何在 scanFrame 对象中调用 notifyBrowser()
2. 或者如何检测 scanFrame 已关闭并在 applet 对象中成功调用 notifyBrowser?

谢谢你的帮助。


所以修改后的代码是这样的:

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);
...

和扫描帧

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');}");
 }

和我得到的错误:

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)
4

1 回答 1

3
  • 如果您需要打开一个单独的窗口,请不要使用 JFrame。使用模态 JDialog,然后控制自动返回到调用代码。
  • 如果您需要将 JApplet 的引用传递给另一个类,只需将其作为构造函数的参数传递。

IE,

ScanFrame scanFrame = new ScanFrame(this); 

其中this代表 JApplet。

请注意,调用Thread.sleep(300L);Swing 事件线程是一个非常糟糕的主意。如果您需要这样的延迟,请使用 Swing Timer,这样您就不会在睡眠期间关闭事件线程。


编辑
你的状态,

我只是复制了一些我在互联网上找到的东西,

这里要小心。复制想法而不是代码,以免您遇到看不见的墙壁。

...但我怀疑这不是要走的路,尽管直到现在我还没有通知任何问题,它解决了 JFrame 落后于浏览器窗口的问题。但问题是,当我通过这个传递applet 对象时,我如何调用它和我的函数notifyBrowser。我的 Netbeans 告诉我将 ScanFrame 构造函数更改为以下内容: public Sc​​anFrame(Runnable aThis)

您的 JApplet 类显然实现了 Runnable,但它也应该扩展 JApplet。请注意,NetBeans 的建议是出于对您计划的无知。IDE 很聪明,但也聪明。您更清楚构造函数参数应该是 JApplet,以便您可以在参数上调用 JApplet 方法。

public class ScanFrame {
   private JApplet myApplet;

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

现在您可以在 myApplet 字段上调用小程序方法。


编辑 2
啊,我的错,我忘了你是从匿名内部类调用构造函数。让我改变一些建议:

  • 首先重命名您的班级。“Applet”已经是某个重要的核心 Java 类的名称,您不想使用它,因为这样做可能会混淆他人或您自己。假设您将其重命名为 ScanFrameApplet。
  • 然后,要在this匿名内部类中获取此小程序this实例ScanFrameApplet.this

IE,

public class ScanFrameApplet extends JApplet {
  try {
    java.awt.EventQueue.invokeAndWait(new Runnable() {
    @Override
    public void run() {
        initComponents();
        ScanFrame scanFrame = new ScanFrame(ScanFrameApplet.this);
于 2013-05-14T22:03:19.243 回答