2013-02-17 33 views
0

我是Java UI和Swing的新手,我無法理解爲什麼會發生這種情況。Swing在invokeLater()上保留着產卵線程

public class ZAsciiMapWindow extends JFrame implements KeyListener, Runnable { 

    ... 

    // SWING STUFF 
    private JTextArea displayArea = null; 
    private JTextField typingArea = null; 

    public ZAsciiMapWindow(final ZMap map, final ZHuman player) { 
     super("ZAsciiMapWindow"); 
     this.map = map; 
     this.player = player; 
    } 

    ... 

    public void show() { 
     try { 
      UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); 
     } catch (UnsupportedLookAndFeelException ex) { 
      ex.printStackTrace(); 
     } catch (IllegalAccessException ex) { 
      ex.printStackTrace(); 
     } catch (InstantiationException ex) { 
      ex.printStackTrace(); 
     } catch (ClassNotFoundException ex) { 
      ex.printStackTrace(); 
     } 
     /* Turn off metal's use of bold fonts */ 
     UIManager.put("swing.boldMetal", Boolean.FALSE); 

     //Schedule a job for event dispatch thread: 
     //creating and showing this application's GUI. 
     javax.swing.SwingUtilities.invokeLater(this); 
    } 

    private void addComponentsToPane() { 

     this.typingArea = new JTextField(20); 
     this.typingArea.addKeyListener(this); 
     this.typingArea.setFocusTraversalKeysEnabled(false); 

     this.displayArea = new JTextArea(); 
     this.displayArea.setEditable(false); 
     JScrollPane scrollPane = new JScrollPane(this.displayArea); 
     scrollPane.setPreferredSize(new Dimension(375, 125)); 

     getContentPane().add(this.typingArea, BorderLayout.PAGE_START); 
     getContentPane().add(scrollPane, BorderLayout.CENTER); 
    } 

    /** 
    * Create the GUI and show it. For thread safety, 
    * this method should be invoked from the 
    * event-dispatching thread. 
    */ 
    private void createAndShowGUI() { 
     //Create and set up the window. 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     //Set up the content pane. 
     this.addComponentsToPane(); 

     //Display the window. 
     this.pack(); 
     this.setVisible(true); 
    } 

    @Override 
    public void run() { 
     createAndShowGUI(); 
    } 
} 

然後當我打電話new ZAsciiMapWindow(x, y).show()從我main(),它只是從來沒有顯示的JFrame。如果我調試,我發現它始終呼籲createAndShowGUI()無限。

這是怎麼發生的?提前致謝。

回答

2

javax.swing.SwingUtilities.invokeLater(this);調用傳遞的Runnable的run方法。您的run方法是createAndShowGUI();,它調用this.setVisible(true);,我假設調用this.show()然後調用javax.swing.SwingUtilities.invokeLater(this);

所以行爲並不是很令人驚訝。

我會先避免讓類擴展JFrame,實現KeyListener和Runnable。

例如,在您的類中有一個JFrame而不是直接擴展JFrame是一個好習慣。

+1

哦,謝謝,我不知道有一個'JFrame.show()'...我沒有假裝覆蓋。關於擴展JFrame,我只是遵循Sun的一個例子......我的意思是Oracle。 – m0skit0 2013-02-17 12:08:21