1

这是来自 Display 的后续问题,并与 Swing 应用程序中的 HTML 表单交互。我已经复制了代码并在 Eclipse (Indigo) 中成功运行了它,但由于某种神秘的原因它停止了工作。我能够连续运行几次,但现在我很幸运,如果我能让它工作的话。

在调试下使用 JUnit 运行它,我已经单步升级了javax.swing.SwingUtilities.invokeLater(new Runnable() {;下一步直接跳到System.in.read()有效地跳过显示逻辑的行。

我怀疑它对invokeLater方法有影响。根据我的研究,invokeLater将其Runnable()放在调度队列中,Runnable只要 VM 接近它就会运行。有人提到,如果Runnable()体验和异常不会“放松”,我认为这意味着它不会关闭并最终会阻塞队列。我怀疑我的一个调用已经停止并且阻塞了队列,但不知道为什么或如何清除队列。

问题:有什么办法可以清除队列?我已经多次停止并重新启动 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类本身中,而是让它围绕着JFrame实例的创建SwingUtilitites.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 回答