Swing在invokeLater()上保持产生线程

时间:2013-02-17 11:53:25

标签: java swing

我是Java UI和Swing的新手,我无法理解为什么会这样。

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()无限。

为什么会这样?提前谢谢。

1 个答案:

答案 0 :(得分: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。