0

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
    So, I did a really quick [proof of concept](https://gist.github.com/RustyKnight/1a85ff63d8cb16d197b8ea19ebf214ed) test which seems to work just fine. This would suggest that there is something else going on which is preventing the dialog from been shown, such as another dialog already open or some other blocking action in the EDT. The question that gets raised in my mind is, why are you prompting for a file location on each `Socket` connection? – MadProgrammer May 18 '18 at 21:51
  • Are you calling `FileTransfListener#run` from within the context of the EDT? – MadProgrammer May 18 '18 at 21:55

1 Answers1

0

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());
}
Antoniossss
  • 31,590
  • 6
  • 57
  • 99
  • 1
    The thing is: i get org.pushingpixels.substance.api.UiThreadingViolationException: Component creation must be done on Event Dispatch Thread if i use the showOpenDialog() directly, at that exact line – Giuseppe Ayanami De Frenza May 18 '18 at 18:58
  • Sorry, IDK pushpixels, that is not part of SWING – Antoniossss May 18 '18 at 18:58
  • Put dialog call and rest of logic on EDT then, but not invoke and wait – Antoniossss May 18 '18 at 19:00
  • I'm getting inconsistent results, first the invokelater worked fine when it only had to show the dialog Then i tried adding more, it continued working, i added even more (the socket and bufferedreader/writer management that i overlooked when submitting the question) and it started doing nothing now i reverted back the code and it still does nothing, what the hell is going on – Giuseppe Ayanami De Frenza May 18 '18 at 19:54
  • Idk i have no clue what code you are talking about. Update question - code is unreadable in comment (cant you see that?)_ – Antoniossss May 18 '18 at 20:07
  • @GiuseppeAyanamiDeFrenza Based on you're updated code, I recommend using a `SwingWorker` instead, but it's difficult to know if that would help without more context to the problem you're trying to solve – MadProgrammer May 18 '18 at 21:53
  • @Antoniossss I did a prove of concept test using `invokeAndWait` showing both a `JFileChooser` and `JOptionPane` without any issues. While I think your "general" advice is correct, there is a deadlock, I don't think the reasoning behind it is - something else is blocking the EDT, but without more context, it's impossible to know what – MadProgrammer May 18 '18 at 21:55
  • It looks like i can't execute the invokelater while there's an open socket. I also can't use a swingworker, since i need to get it done on the EDT. I'll have to study it further – Giuseppe Ayanami De Frenza May 19 '18 at 08:36