2012-10-25 75 views
1

这是从Display and interact with an HTML form in a Swing application开始的问题。我已经复制了代码并在Eclipse(Indigo)中成功运行它,但出于某种神秘的原因,它停止工作。我能够连续运行数次,但现在我很幸运,如果我能够完全实现它的话。JFrame在之前显示之前停止显示

在调试下运行它与JUnit,它我单步加强到javax.swing.SwingUtilities.invokeLater(new Runnable() {行;下一步直接跳到System.in.read()行,有效地跳过显示逻辑。

我怀疑它有一些东西给invokeLater方法。从我的研究中,invokeLater将其Runnable()放在调度队列中,并且每当VM接近它时将运行Runnable。有一些提到,如果一个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(); 
    } 
} 
} 
+1

你试过'SwingUtilities.invokeAndWait'代替? – MadProgrammer

+0

@MadProgrammer +1是可以工作的。 –

回答

2

是否有可能尽可能的Java来讲JFrame是 显示,但它实际上没有显示出来在屏幕上,我可以 击中提交按钮?什么会造成这种情况?为什么它会连续数次运行 ,然后突然停止?

是的,因为您在JFrame实例上调用setVisible(true)实例,然后再添加所有组件。

也有在你的代码中的其他异常可能导致的问题:只设置JFrame可见 前

  • 不要调用JFrame#setVisible(true)所有组件之前已被添加到JFrame
  • 不要调用JFrame#setSize(..),而调用JFrame#pack()
  • 您的SwingUtilities.invokeLater(..)不应该嵌套在JFrame类本身中,而应该使其包含在中以创建JFrame实例
  • 不要电话System.in.read()这将阻止EDT线程和你的用户界面将冻结
  • 不要依靠调用创建JFrame实例(testForms())的方法,确保JFrame实例类的构造函数中创建。

这里是
的一个实例我做:

enter image description here

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); 
    } 
} 
+0

+1不错的工作! ... – MadProgrammer

+1

感谢您的新例子和建议。在这方面仍然是新的,只是做了一个简单的代码剪切和粘贴,所以我可以玩它。 它必须是JUnit的东西,因为当通过JUnit的测试存根运行示例时,它的行为方式是相同的 - 跳过显示逻辑。同时运行我的原始和您的示例与静态main()每次都一直工作。 –