Reliably setting the system clipboard in a spawned thread and having the spawner wait Checklist from FAQ for proper posting.

Does my question contain code? 
   - YES
Did I write that code?
   - YES
Is it actual code from a project rather than pseudo-code or example code?
   - Strait from actual code, minus a few functions that do not apply to the Q
To the best of my knowledge, does the code work?
   - To the best of my knowledge it works most of the time, other times it 
     fails to do what I ask of it but produces no runtime errors. 
Do I want feedback about any or all facets of the code?
   - Just about how to reliably wait for the clipboard to be set and 
     reliably set it while I am waiting.


I am trying to reliably set the system clipboard text in my program but keep coming back with confusing results. Those results being it sometimes setting the text and sometimes not setting it. Here is where I create a thread of type ClipSetThread and tell it to set the system clipboard and also set a global variable called waitForMe in the main Application.

public void setClip(String arg) // Starts a clip setting thread
{
    CLUtilCompact.waitForMe = true;
    ClipSetThread set = new ClipSetThread(theApp);
    set.arg = arg;
    set.start();
    while(CLUtilCompact.waitForMe){}
}


And here is the class ClipSetThread

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;

public class ClipSetThread extends Thread
{
String arg = "";
Clipboard sysClip = null;
CLUtilCompact theApp = null;
public ClipSetThread(CLUtilCompact app)
{
    theApp = app;
    theApp.updateOutput("Set Clip ID:" + this.getId() + "|CREATED");
    sysClip = Toolkit.getDefaultToolkit().getSystemClipboard();
}
public void run()
{
    setClip2(arg);
    CLUtilCompact.waitForMe = false;
    return;
}
public void setClip2(String arg)
{
    while(true) 
    {
        try
        {
            sysClip.setContents(new StringSelection(arg), null);
        }
        catch(Exception e)
        {
            try {Thread.sleep(20);} catch (InterruptedException e1) {}
            continue;
        }
        break;
    }
    return;
}
}


It seems that even with the while loop to wait for the waitForMe flag the setClip function will return and allow the application to try and continue what it is doing even though the clipboard is not set. 

After the clipboard is set I almost always try to paste what is there; I usually call Thread.sleep(1000) between a call to setClip and my call to paste(). (Paste simply simulates ctrl+V with the java Robot class)
This code is quite confusing. Do you know about parallel threads mechanisms?

CLUtilCompact.waitForMe = true;
set.start();


A new thread is started now and executes the run method from the interface. It is not defined when the thread is run, how fast and when he will execute any statements (and can not, the OS is responsible for this, not the JVM)

So, sometimes, this lines is called first:

while(CLUtilCompact.waitForMe){}


Sometimes this line is called first:

CLUtilCompact.waitForMe = false;


Even if the second line is called first, nobody knows when the field update will propagate to the other thread.

What we can do about this? In general, nothing. This is the (desired) behavior of threads.
For your problem, you can either block the application until the job is done, or hope that it is done fast enough asynchronously. You could implement some logic, which will display some error message after a given time. But this is quite a bad solution for slow system or systems under heavy load.

If you want to do something after the run method has finished, try SwingWorker (read the java documentation).



Some more things:

ClipSetThread set = new ClipSetThread(theApp);
set.arg = arg;


Use the constructor, add a second argument.



while(true) 
{
    try
    {
        sysClip.setContents(new StringSelection(arg), null);
    }
    catch(Exception e)
    {
        try {Thread.sleep(20);} catch (InterruptedException e1) {}
        continue;
    }
    break;
}
return;


Without discussing the pattern, this could be more readable:

boolean isSuccessful = false;
while(!isSuccessful) {
    try {
        sysClip.setContents(new StringSelection(arg), null);
        isSuccessful = true;
    }
    catch(Exception e) {
        try {Thread.sleep(20);} catch (InterruptedException e1) {} //you could use a method wait(seconds) for this
    }
}
return;


And you should, if possible, document inside the catch block why you are doing nothing there.