ユーザーを自動化できる Automator クラスがあります。Windowsでシステムクリップボードを設定する際に特に問題があります。Automator クラスは、システム クリップボードを設定するスレッドである ClipSetThread クラスを利用します。ClipSetThread のインスタンスは入力としてスレッドを取り、null の場合は結合します (完了するのを待ちます)。
私は ClipSetThread を正しく呼び出していないと感じています。これは、信頼性に関して以前に発生したエラーがまだ残っているためです。ClipSetThread の前。このコードは実行時にエラーをスローしませんが、約 2/3 の時間で動作します。それ以外の場合は、1134、_234 などを出力します。スレッドが互いに結合 (待機) していないか、スキップされているようです。
コード:
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.mouse.NativeMouseEvent;
import org.jnativehook.mouse.NativeMouseInputListener;
public class Automator extends Thread implements NativeMouseInputListener 
{
Robot rob = null;
TheAppClass theApp = null;
ClipSetThread lastClipSet = null; 
boolean doit = false;
boolean settingClip = false;
public void run()
{
    try // to make the Global hook
    {
        GlobalScreen.registerNativeHook();
    }
    catch (NativeHookException ex){theApp.updateOutput("No Global Keyboard or Mouse Hook");return;}
    try // to create a robot (can simulate user input such as mouse and keyboard input)
    {
        rob = new Robot();
    } 
    catch (AWTException e1) {theApp.updateOutput("The Robot could not be created");return;}
    while(true) {}
}
public void setApp(TheAppClass app)
{
    theApp = app;
    theApp.updateOutput("Succesfully started automator");
}
public void setClip(String arg)
{
    ClipSetThread set = new ClipSetThread(theApp, lastClipSet);
    lastClipSet = set;
    set.setClip(arg);
}
public void DOit()
{
    theApp.updateOutput("Starting");
    pasteAtCursorLocation("1");
    tab(1);
    pasteAtCursorLocation("2");
    tab(1);
    pasteAtCursorLocation("3");
    tab(1);
    pasteAtCursorLocation("4");
    tab(1);
    theApp.updateOutput("Complete");
}
public void nativeMouseReleased(NativeMouseEvent e) 
{
    //System.out.println("Mouse Released: " + e.getButton());
    if(doit)
    {
        DOit();
        doit = false;
    }
}
public void pasteAtCursorLocation(String text)
{
    setClip(text);
    rob.keyPress(KeyEvent.VK_CONTROL);
    rob.keyPress(KeyEvent.VK_V);
    rob.keyRelease(KeyEvent.VK_V);
    rob.keyRelease(KeyEvent.VK_CONTROL);
    theApp.updateOutput("Simulated Paste");
}
public void tab(int numTimes)
{
    while(numTimes > 0)
    {
        rob.keyPress(KeyEvent.VK_TAB);
        rob.keyRelease(KeyEvent.VK_TAB);
        numTimes--;
        theApp.updateOutput("Simulated Tab");
    }
}
// Unimplemented
public void nativeMouseClicked(NativeMouseEvent arg0) {}
public void nativeMousePressed(NativeMouseEvent arg0) {}
public void nativeMouseDragged(NativeMouseEvent arg0) {}
public void nativeMouseMoved(NativeMouseEvent arg0) {}
}
クリップセット スレッド:
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 
{
Clipboard sysClip = null;
TheAppClass  theApp = null;
public ClipSetThread(TheAppClass  app, Thread waitFor)
{
    theApp = app;
    sysClip = Toolkit.getDefaultToolkit().getSystemClipboard();
    if(waitFor != null)
        {try {waitFor.join();}catch (InterruptedException e) {}}
}
public void setClip(String arg)
{
    // Two strings that will hopefully never be on the clipboard
    String checkStr1 = "9999999999999";
    String checkStr2 = "99999999999999";
    // When we read in the clipboard we want to see if we change these strings from the ones they
    // will never be, if they do change we read the clipboard successfully
    String clipBoardTextBefore = checkStr1;
    String clipBoardTextAfter = checkStr2;
    // First get a copy of the current system clipboard text
    while(true)
    {
        try 
        {
            Transferable contents = sysClip.getContents(null);
            clipBoardTextBefore = (String)contents.getTransferData(DataFlavor.stringFlavor);
        }
        catch(Exception e)
        {
            try {Thread.sleep(20);} catch (InterruptedException e1) {}
            continue;
        }
        break;
    }
    // If we failed to change the string it means we failed to read the text
    if(clipBoardTextBefore.equals(checkStr1)) 
        theApp.updateOutput("Could NOT get sysClip text");
    else
    {
        // If we didn't failed to get the current text try to change it
        while(true) 
        {
            try{sysClip.setContents(new StringSelection(arg), null);}
            catch(Exception e)
            {
                try {Thread.sleep(20);} catch (InterruptedException e1) {}
                continue;
            }
            break;
        }
        // Now again check to see the clipboard text
        while(true)
        {
            try 
            {
                Transferable contents = sysClip.getContents(null);
                clipBoardTextAfter = (String)contents.getTransferData(DataFlavor.stringFlavor);
            }
            catch(Exception e)
            {
                try {Thread.sleep(20);} catch (InterruptedException e1) {}
                continue;
            }
            break;
        }
        // If we failed to read the clipboard text
        if(clipBoardTextAfter.equals(checkStr2)) 
            theApp.updateOutput("Could NOT check if sysClip update was successful");
        else
        { // We re-read the clipboard text, see if it changed from the original clipboard text 
            if(clipBoardTextAfter.equals(checkStr1)) 
                theApp.updateOutput("Could NOT successfully set clipboard text");
            else
                theApp.updateOutput("Set Clipboard Text:" + arg + "\n");
        }
    }
}
}