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.