views:

9

answers:

0

Hi, this is my first question here on stackoverflow. I am making a pretty sweet Java MIDlet that lets me control my computer from my cell phone, using either an Internet socket, Bluetooth connection, or USB connection. I created a custom class called Robot which sends data over the network with a DataOutputStream. It looks exactly the same as the regular Robot class from java.awt.Robot.

public class Robot {

    public static final byte MOUSE_MOVE_ABS = 0x01;
    public static final byte MOUSE_MOVE_REL = 0x02;
    public static final byte MOUSE_PRESS = 0x03;
    public static final byte MOUSE_RELEASE = 0x04;
    public static final byte MOUSE_WHEEL = 0x05;
    public static final byte KEY_PRESS = 0x06;
    public static final byte KEY_RELEASE = 0x07;
    public static final byte TYPE = 0x08;
    public static final byte SCREEN_CAPTURE = 0x09;

    public static final int BUTTON_LEFT = 16;
    public static final int BUTTON_RIGHT = 4;
    public static final int BUTTON_MIDDLE = 8;

    private DataOutputStream output;
    private DataInputStream input;
    private boolean flushing = true;

    public Robot(DataOutputStream output, DataInputStream input) {
        this.output = output;
        this.input = input;
    }

    public Robot(DataOutputStream output, DataInputStream input, boolean useFlushing) {
        this(output, input);
        flushing = useFlushing;
    }

    public void mouseMove(int x, int y) throws IOException {
        output.writeByte(MOUSE_MOVE_ABS);
        output.writeShort(x);
        output.writeShort(y);
        if( flushing ) output.flush();
    }

    public void mouseMoveRel(int x, int y) throws IOException {
        output.writeByte(MOUSE_MOVE_REL);
        output.writeShort(x);
        output.writeShort(y);
        if( flushing ) output.flush();
    }

    public void mousePress(int keycode) throws IOException {
        output.writeByte(MOUSE_PRESS);
        output.writeShort(keycode);
        if( flushing ) output.flush();
    }

    public void mouseRelease(int keycode) throws IOException {
        output.writeByte(MOUSE_RELEASE);
        output.writeShort(keycode);
        if( flushing ) output.flush();
    }

    public void mouseClick(int keycode) throws IOException {
        mousePress(keycode);
        mouseRelease(keycode);
        if( flushing ) output.flush();
    }

    public void mouseWheel(int amount) throws IOException {
        output.writeByte(MOUSE_WHEEL);
        output.writeShort(amount);
        if( flushing ) output.flush();
    }

    public void keyPress(int key) throws IOException {
        output.writeByte(KEY_PRESS);
        output.writeShort(key);
        if( flushing ) output.flush();
    }

    public void keyRelease(int key) throws IOException {
        output.writeByte(KEY_RELEASE);
        output.writeShort(key);
        if( flushing ) output.flush();
    }

    public void type(String text) throws IOException {
        output.writeByte(TYPE);
        output.writeUTF(text);
        if( flushing ) output.flush();
    }

    public Image createScreenCapture(int x, int y, int w, int h) throws IOException {
        output.writeByte(SCREEN_CAPTURE);
        output.writeShort(x);
        output.writeShort(y);
        output.writeShort(w);
        output.writeShort(h);
        int length = input.readShort();
        int[] rgb = new int[length];
        for( int i = 0; i < length; i++ ) {
            rgb[i] = input.readInt();
        }
        Image image = Image.createRGBImage(rgb, w, h, false);
        return image;
    }

}

However, methods such as createScreenCapture() would take a very long time. My question is: what is a good way to make each method call in the Robot class be run in a separate thread than the threads which run pointerPressed(), pointerDragged(), and pointerReleased()? What is the recommended way to handle this?

Here is a simplified example of what I have currently (Right now I know it's not the best way to do this, since calling robot.whatever() can take a while):

public class Control extends Canvas {

    Robot robot;

    boolean connected = false;

    public Control(int type, String host) {
        this.type = type;
        this.host = host;
        connect();
    }

    public void connect() {

        updateScreen();

        new Thread(new Runnable() {

            public void run() {

                try {
                    SocketConnection con = (SocketConnection) Connector
                            .open("socket://" + host);
                    DataOutputStream os = con.openDataOutputStream();
                    robot = new Robot(os);
                    connected = true;
                    while (true) {
                        updateScreen();
                        try {
                            Thread.sleep(40);
                        } catch (InterruptedException e) {
                        }
                    }
                } catch (IOException x) {
                }
            }

        }).start();
    }

    public void updateScreen() {
        repaint();
    }

    public void paint(Graphics graphics) {
        // whatever i had here...
    }

    public void pointerPressed(int x, int y) {
    }

    public void pointerDragged(int x, int y) {
            robot.mouseMove(x, y);
    }

    public void pointerReleased(int x, int y) {
    }

    public void keyPressed(int key) {
        if (connected) {
            try {
                if (key == -8) {
                    robot.mouseClick(Robot.BUTTON_RIGHT);
                }
            } catch (Exception e) {
            }
        }
    }

    public void keyRepeated(int key) {
        if (connected) {
            try {
                if (key == -102) {
                    // Up
                    robot.mouseWheel(-1);
                } else if (key == -103) {
                    // Down
                    robot.mouseWheel(1);
                }
            } catch (Exception e) {
            }
        }
    }

}

I hope my code isn't to long.. I know the answer can help a lot of people since doing stuff like this (doing long-running operations from canvas events) is fairly common I'm guessing.