Open another instance of JFrame (from a JFrame): use EventQueue.invokeLater? (event dispatch thread)

StackOverflow https://stackoverflow.com/questions/21365432

سؤال

Some related questions:

I want to open a second JFrame window from the first. The first has a main() method, and button click handler which would open the second JFrame. (Beware of typos, I condensed it).

What is good practice for creating the second JFrame? (It has to be a JFrame I think.) I will want to be able to close the first JFrame and leave the second one running, as they don't talk to each other after the first instantiates the second with some data.

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                MyMainClass window = new MyMainClass();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}
public MyMainClass() {
    initialize();
}
private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 697, 416);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //...       
    JButton btnNewButton = new JButton("Open Second Window");
    btnNewButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {

        // Would this be the correct thing to do?
        // If this first window is closed, would it
        // close the second one as well? (not what I want)

        new SecondFrame();

        }
    });
    //...       
}

public class SecondFrame extends JFrame {
    private JPanel contentPane;
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    SecondFrame frame = new SecondFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    public SecondFrame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);
    }

}

I don't understand why it is said to be important to use the event dispatch thread.

I'm guessing the code in the main() function of SecondFrame won't get called, so instead, its contents should be moved to the button's event handler, replacing the statement new SecondFrame();? Or can I just leave the button's click handler as it is, and remove the main() method of SecondFrame altogether? (Except for the setVisible(true); statement)

Thanks!

هل كانت مفيدة؟

المحلول

All the Swing listeners are executed in the event dispatch thread, unlike the main method of a Java program. So, when the button on the first frame is clicked, you're already in the EDT, and there's no need to use EventQueue.invokeLater() to open the second one.

The main method in the second JFrame is indeed useless if you don't plan to use it. Just create an instance of your second frame, and make it visible:

SecondFrame frame = new SecondFrame();
frame.setVisible(true);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top