简体   繁体   中英

Java Swing - Close JDialog from external Thread

I am working with Swing right now and I do not get this to work properly.

What I need is the following:

I've got a class "Client" that is able to connect to a TCP server. If the connection fails (wrong IP for example), then it will show an error dialog that can be closed by clicking on the "OK" Button.

However if the client connected successfully, a window should popup that runs until my client receives a specific message from the server.

My code looks like this:

if(ip != null) {
    Client c = new Client();
    try{

        c.connect(ip, 56556);

        JOptionPane msg = new JOptionPane("Connecting...", JOptionPane.INFORMATION_MESSAGE);
        JDialog dlg = msg.createDialog("Connecting...");
        dlg.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
        dlg.setVisible(true);

        c.addIncomingMessageHandler(new IncomingMessageHandler(){
           @Override
           public void incomingMessage(Connection<?> cnctn, Object o) {
               dlg.setVisible(false);
               dlg.dispose();
           }
       });

   }catch(Exception e) {
       int n = JOptionPane.showOptionDialog(this, "Oops! Something went wrong!",
            "Title", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE,
            null, new Object[] {"OK"}, JOptionPane.OK_OPTION);
        }
}

So the exception is throws if c.connect() fails. c.addIncomingMessageHandler() is a listener that listens to any incoming messages to the client. If the server sends something, this method will be called. If that's the case, the JDialog will be closed. But this window can be closed right now by clicking on the OK-Button.

在此处输入图片说明

I'd like to rename that button and add a function. The new text should be "Cancel" and if the button is pressed, the client should be closed (c.disconnect) and the window itself should be closed as well.

How could I do that?

From the Documentation:

Stopping Automatic Dialog Closing

By default, when the user clicks a JOptionPane-created button, the dialog closes. But what if you want to check the user's answer before closing the dialog? In this case, you must implement your own property change listener so that when the user clicks a button, the dialog does not automatically close.

DialogDemo contains two dialogs that implement a property change listener. One of these dialogs is a custom modal dialog, implemented in CustomDialog , that uses JOptionPane both to get the standard icon and to get layout assistance. The other dialog, whose code is below, uses a standard Yes/No JOptionPane . Though this dialog is rather useless as written, its code is simple enough that you can use it as a template for more complex dialogs.

Besides setting the property change listener, the following code also calls the JDialog's setDefaultCloseOperation method and implements a window listener that handles the window close attempt properly. If you do not care to be notified when the user closes the window explicitly, then ignore the bold code.

final JOptionPane optionPane = new JOptionPane(
                "The only way to close this dialog is by\n"
                + "pressing one of the following buttons.\n"
                + "Do you understand?",
                JOptionPane.QUESTION_MESSAGE,
                JOptionPane.YES_NO_OPTION);

final JDialog dialog = new JDialog(frame, 
                             "Click a button",
                             true);
dialog.setContentPane(optionPane);
dialog.setDefaultCloseOperation(
    JDialog.DO_NOTHING_ON_CLOSE);
dialog.addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent we) {
        setLabel("Thwarted user attempt to close window.");
    }
});
optionPane.addPropertyChangeListener(
    new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent e) {
            String prop = e.getPropertyName();

            if (dialog.isVisible() 
             && (e.getSource() == optionPane)
             && (prop.equals(JOptionPane.VALUE_PROPERTY))) {
                //If you were going to check something
                //before closing the window, you'd do
                //it here.
                dialog.setVisible(false);
            }
        }
    });
dialog.pack();
dialog.setVisible(true);

int value = ((Integer)optionPane.getValue()).intValue();
if (value == JOptionPane.YES_OPTION) {
    setLabel("Good.");
} else if (value == JOptionPane.NO_OPTION) {
    setLabel("Try using the window decorations "
             + "to close the non-auto-closing dialog. "
             + "You can't!");
}

Click here !

Related question .

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