简体   繁体   中英

Event handler in JDialog not working if placed after setVisible(true)

This is an interesting problem that didn't show up when I built the last JDialog, even though that one was way more complex than this. Anyways here is the code that causes the problem.

public class Test extends JDialog{

private final JButton cancel, ok;
private final JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 50, 5));

public Test(JFrame parent) {
    //Initialize the JDialog
    super(parent, "Select Chapters");
    setLayout(new BorderLayout());
    setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
    setModalityType(JDialog.ModalityType.APPLICATION_MODAL);
    setSize(300, 300);
    setLocationRelativeTo(null);


    cancel = new JButton("Cancel");
    ok = new JButton("OK");
    buttonPanel.add(cancel);
    buttonPanel.add(ok);
    getContentPane().add(buttonPanel, BorderLayout.SOUTH);



    setVisible(true);

    cancel.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent ae) {
            dispose();
        }
    });


}}

And the main method

Test test = new Test(new JFrame());

I put the event listener in the constructor for testing but the actual implementation is supposed to happen in another class. Which is why this is a problem. If I put the action listener before setVisible(true), then everything works as it should. But I can't do that since the event handler is to be implemented in another class. What is causing this problem and how do I resolve it?

Event handler in JDialog not working if placed after setVisible(true)

Correct, because the JDialog is modal, so the statement after the setVisible() is not executed until the dialog is closed.

There is no reason you can't add the ActionListener to the button before the dialog is made visible. It doesn't matter that the code is in a separate class. You just create an instance of that class in the constructor of the class where you create the button.

I put setVisible() in the other class after I implemented the listeners

You are still doing something wrong. The setVisible() should be in your main class where you set the dialog properties and create all the components and add the component to the dialog.

I'm not sure why you are doing. Your code can be something like:

cancel = new JButton("Cancel");
cancel.addActionListener( new SomeActionListenerClass() );
...
setVisible( true );

You need to place setVisible(true) at the end of your constructor because the dialog is modal and in that case setVisible(true) will not return until you call setVisible(false).

Quoting Java doc: https://docs.oracle.com/javase/7/docs/api/java/awt/Dialog.html#setVisible(boolean)

Notes for modal dialogs.

setVisible(true): If the dialog is not already visible, this call will not return until the dialog is hidden by calling setVisible(false) or dispose.

setVisible(false): Hides the dialog and then returns on setVisible(true) if it is currently blocked.

It is OK to call this method from the event dispatching thread because the toolkit ensures that other events are not blocked while this method is blocked.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM