1

これは、Swing アプリケーションでの HTML フォームの表示と操作に関する質問の続きです。コードをコピーして、Eclipse (Indigo) で正常に実行しましたが、何らかの不思議な理由で動作しなくなりました。何回か続けて実行することができましたが、今はまったく動作させることができればラッキーです。

デバッグ中に JUnit を使用して実行すると、そのjavax.swing.SwingUtilities.invokeLater(new Runnable() {行にステップアップしました。System.in.read()次のステップでは、表示ロジックを実質的にスキップして、行に直接ジャンプします。

invokeLater私はそれがメソッドに何かを持っているのではないかと疑っています。私の調査によると、それをディスパッチ キューにinvokeLater入れると、VM がそれに近づくたびに実行されます。経験と例外が「巻き戻されない」という言及がいくつかあります。これは、それが閉じず、キューをブロックしてしまうことを意味すると思います。呼び出しの 1 つが停止し、キューが詰まっていると思われますが、キューをクリアする理由や方法がわかりません。Runnable()RunnableRunnable()

質問: キューをクリアする方法はありますか? ディスパッチ キューがクリアされると考えて、Eclipse を何度か停止して再起動しましたが、うまくいきませんでした。

Javaに関する限り、表示されている可能性はありますがJFrame 実際には画面に表示されていないため、送信ボタンを押すことができますか? これは何が原因でしょうか?数回続けて動作し、突然停止するのはなぜですか?

以下は関連コードです。

JUnit スタブ:

@Test
public final void testTestForms()  {
    // https://stackoverflow.com/questions/6145405/display-and-interact-with-an-html-form-in-a-swing-application
    Navigate n = new Navigate();
    try {
        n.testForms();
        n= null;  // in desperate attempt to garbage collect
    } catch (IOException e) {
        System.out.println("Error invoking n.testForms()");
        e.printStackTrace();
        n= null;
    }
    n = null;

}

研究対象:

public class Navigate  {
@Test
public void testForms() throws IOException {
    System.out.println("in testForms()");
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            System.out.println("in run()");
            javax.swing.JFrame jf = new javax.swing.JFrame();
            jf.setSize(300, 300);
            jf.setVisible(true);
            jf.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);

            JTextPane textPane = new JTextPane();
            textPane.setContentType("text/html");
            textPane.setEditable(false);
            textPane.setText("<html>" + "<body>" + "<form action=\"#\">"
                    + "<input name=\"input1\" type=\"text\" />"
                    + "<input name=\"input2\" type=\"text\" /><br/>"
                    + "<input name=\"cb1\" type=\"checkbox\" /><br/>"
                    + "<input name=\"rb1\" type=\"radio\" /><br/>"
                    + "<input type=\"submit\" value=\"go\" />" + "</form>"
                    + "</body>" + "</html>");

            jf.getContentPane().setLayout(
                    new BoxLayout(jf.getContentPane(), BoxLayout.Y_AXIS));

            jf.getContentPane().add(textPane);

            HTMLEditorKit kit = (HTMLEditorKit) textPane.getEditorKit();
            kit.setAutoFormSubmission(false);
            textPane.addHyperlinkListener(new HyperlinkListener() {
                public void hyperlinkUpdate(HyperlinkEvent e) {
                    if (e instanceof FormSubmitEvent) {
                        System.out.println(((FormSubmitEvent) e).getData());
                    }
                }
            });
        }
    }
);
    // try to catch exceptions that could plug the queue?
    try {
        System.in.read();
    } catch (IOException e) {
    System.out.println("Error with System.in.read()");
        e.printStackTrace();
        throw new IOException(e);
    }
    try {
        finalize();  // another desperate attempt
    } catch (Throwable e) {
        e.printStackTrace();
    }
}
}
4

1 に答える 1

2

Javaに関する限り、JFrame表示されている可能性はありますが、実際には画面に表示されていないため、送信ボタンを押すことができますか? これは何が原因でしょうか?数回続けて動作し、突然停止するのはなぜですか?

はい。すべてのコンポーネントが追加される前setVisible(true)にインスタンスを呼び出すためです。JFrame

コードには、問題を引き起こす可能性のある他の異常もあります。

  • JFrame#setVisible(true)すべてのコンポーネントが追加される前に呼び出さないでくださいJFrame
  • 可視に設定する直前に呼び出すのJFrame#setSize(..)ではなく呼び出すJFrame#pack()JFrame
  • クラス自体にネストSwingUtilities.invokeLater(..)するのではなく、インスタンスJFrameの作成を囲むようにします。JFrameSwingUtilitites.invokeLater(...)
  • これを呼び出さないSystem.in.read()でください。EDT スレッドがブロックされ、UI がフリーズします。
  • JFrameインスタンス ( )を作成するメソッドの呼び出しに依存しないでください。インスタンスがクラス コンストラクター内で作成されてtestForms()いることを確認してください。JFrame

これが私が作った例です:

ここに画像の説明を入力

import javax.swing.BoxLayout;
import javax.swing.JTextPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.html.FormSubmitEvent;
import javax.swing.text.html.HTMLEditorKit;

public class JavaApplication26 {

    public static void main(String[] args) {

        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                //create new instance of JFrame
                new Navigate();
            }
        });
    }
}

class Navigate {

    public Navigate() {
        initComponents();
    }

    private void initComponents() { //this is a constructor

        javax.swing.JFrame jf = new javax.swing.JFrame();
        jf.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);

        JTextPane textPane = new JTextPane();
        textPane.setContentType("text/html");
        textPane.setEditable(false);
        textPane.setText("<html>" + "<body>" + "<form action=\"#\">"
                + "<input name=\"input1\" type=\"text\" />"
                + "<input name=\"input2\" type=\"text\" /><br/>"
                + "<input name=\"cb1\" type=\"checkbox\" /><br/>"
                + "<input name=\"rb1\" type=\"radio\" /><br/>"
                + "<input type=\"submit\" value=\"go\" />" + "</form>"
                + "</body>" + "</html>");

        HTMLEditorKit kit = (HTMLEditorKit) textPane.getEditorKit();
        kit.setAutoFormSubmission(false);
        textPane.addHyperlinkListener(new HyperlinkListener() {
            @Override
            public void hyperlinkUpdate(HyperlinkEvent e) {
                if (e instanceof FormSubmitEvent) {
                    System.out.println(((FormSubmitEvent) e).getData());
                }
            }
        });

        //add components
        jf.getContentPane().setLayout(new BoxLayout(jf.getContentPane(), BoxLayout.Y_AXIS));
        jf.getContentPane().add(textPane);

        jf.pack();//pack
        jf.setVisible(true);
    }
}
于 2012-10-25T06:14:53.543 に答える