1

「init」中にJFrameを開始するJAppletがあります。JFrame にはいくつかの操作があり、ユーザーは最終的に JFrame を閉じます。

ここで、何かを行う必要があることを JavaScript を介してブラウザに通知したいと思います。

それを達成する方法は?アプレット単体なら以下の簡単な関数で十分

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

しかし、コード内の「これ」はアプレットオブジェクトを参照しており、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();
}
}

したがって、私の質問は次の
とおり
です。

ご協力いただきありがとうございます。


したがって、変更されたコードは次のようになります。

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 の参照を別のクラスに渡す必要がある場合は、単純にコンストラクタのパラメータとして渡します。

つまり、

ScanFrame scanFrame = new ScanFrame(this); 

ここでthis、JApplet を表します。

Thread.sleep(300L);Swing イベント スレッドでの呼び出しは、非常に悪い考えであることに注意してください。このような遅延が必要な場合は、スイング タイマーを使用して、スリープ中にイベント スレッドをシャットダウンしないようにします。



あなたの状態を編集し、

ネットで見つけたものをコピペしただけで、

ここで注意してください。目に見えない壁にぶつからないように、コードではなくアイデアをコピーします。

...しかし、これまでは問題を通知しておらず、JFrame がブラウザ ウィンドウの背後にある問題は解決されましたが、それではいけないと思いました。しかし問題は、これを介してアプレット オブジェクトを渡すときに、どのようにそれと関数 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
ああ、悪いことですが、匿名の内部クラスからコンストラクターを呼び出していたことを忘れていました。いくつかの推奨事項を変更させてください。

  • まず、クラスの名前を変更します。「アプレット」はすでに重要なコア Java クラスの名前であり、これを行うと他の人や自分自身を混乱させる可能性があるため、使用したくありません。名前を ScanFrameApplet に変更するとします。
  • 次にthis、匿名の内部クラス内でこのアプレットのインスタンスのを取得するにはthis、 の前にクラス名を付ける必要があるため、私のインスタンスではScanFrameApplet.this.

つまり、

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 に答える