SwingUtilities.InvokeAndWait() doesn't execute the runnable code

517 Views Asked by At

I'm writing a thread code that opens a server socket and that when reached by a connection asks the user to choose a directory. I've tried using the InvokeLater() and it works, but i have no control on when to retrieve the selected file directory, so InvokeAndWait looked like the right alternative. Except it doesn't actually do anything, i've even tried givin it a println and it simply does not seem to execute anything. How do i fix it? I'm running out of ideas. Thanks!

public class FileTransfListener implements Runnable {

protected JFileChooser dirChooser;

public FileTransfListener(JFileChooser f){
    dirChooser=f;
}

@Override
public void run() {
    ServerSocket serverSocket = null;
    Socket socket = null;
    BufferedReader in = null;
    BufferedWriter out = null;
    try {
        serverSocket = new ServerSocket(60905);
    } catch (IOException e1) {
        return;
    }
    while(true){
        try {
            socket = serverSocket.accept();
            String dir=null;

            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    dirChooser.showOpenDialog(null);
                }
            });

            try{
                dir= dirChooser.getSelectedFile().getAbsolutePath();
            }
            catch(NullPointerException e){
                dir=null;
            }
            System.out.println(dir);
            }
            catch (IOException  ex) {
            ex.printStackTrace();
            try {
                serverSocket.close();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        } catch (InvocationTargetException |InterruptedException e1) {
            e1.printStackTrace();
        }
    }

}

}

1

There are 1 best solutions below

8
On

Its a deadlock

dirChooser.showOpenDialog(null); is a blocking method and you should use it directly not trough SwingUtilities

What happens here is:

  1. SwingUtilities.invokeAndWait submits task to EDT - blocks until it is completed
  2. dirChooser.showOpenDialog(null); schedules dialog draw to EDT - awaits unitl dialog is closed - but its never drawn....
  3. Since invokaAndWait awaits for completion on EDT - event queue is not emptied and task awaits for itself to complete - deadlock

What you should do is to call directly without EDT queue. Documentation has simple exmaple of this:

JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(
    "JPG & GIF Images", "jpg", "gif");
chooser.setFileFilter(filter);
int returnVal = chooser.showOpenDialog(parent);
if(returnVal == JFileChooser.APPROVE_OPTION) {
   System.out.println("You chose to open this file: " +
        chooser.getSelectedFile().getName());
}