Fun with Robot
Enter Robot
In addition to being able to inject mouse and keyboard events into the system java.awt.Robot gives you the ability render part of the desktop into an image. Exactly what I want. The following code grabs a screen shot returning a BufferedImage:Robot robot = new Robot(); BufferedImage image = robot.createScreenCapture(new Rectangle(x, y, width, height));So Robot gives me an image of part of the desktop, but I don't really want to continually do a keyboard gesture to create the image. I want the image to update as I move the mouse around.
Enter AWTEventListener
AWTEventListener can be used to listen to all events. Think of it as a way to globally install a *Listener. Using AWTEventListener I can determine when the mouse moves over any component. Here's the code for that:
Toolkit toolkit = Toolkit.getDefaultToolkit();
AWTEventListener listener = new AWTEventListener() {
public void eventDispatched(AWTEvent event) {
if (event.getID() == MouseEvent.MOUSE_MOVED) {
mouseMoved(event);
}
}
};
toolkit.addAWTEventListener(new , AWTEvent.MOUSE_MOTION_EVENT_MASK);
Combining AWTEventListener with Robot I have a way to zoom in on part
of my window as the cursor is being moved. Excellent! The following
screen shot shows this in effect. The bottom area is the zoomed in
component.
Here's the code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class MagnifyComponent extends JComponent {
private int factor;
private Image image;
private int w;
private int h;
private Robot robot;
MagnifyComponent() {
try {
robot = new Robot();
} catch (AWTException e) {
}
this.factor = 6;
Toolkit.getDefaultToolkit().addAWTEventListener(
new EventHandler(), AWTEvent.MOUSE_MOTION_EVENT_MASK);
}
public void reshape(int x, int y, int w, int h) {
super.reshape(x, y, w, h);
updateImageSize();
}
private void updateImageSize() {
int w = getWidth();
int h = getHeight();
image = null;
this.w = w / factor / 2;
this.h = h / factor / 2;
}
public void paintComponent(Graphics g) {
if (isOpaque()) {
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
}
if (image != null) {
g.drawImage(image, 0, 0, w * factor * 2, h * factor * 2,
0, 0, w + w, h + h, null);
}
}
private void updateImage(int x, int y) {
if (w > 0 && h > 0) {
image = robot.createScreenCapture(new Rectangle(
x - w, y - h, w + w, h + h));
}
repaint();
}
private class EventHandler implements AWTEventListener {
public void eventDispatched(AWTEvent event) {
if (event.getID() == MouseEvent.MOUSE_MOVED) {
MouseEvent me = (MouseEvent)event;
Component source = me.getComponent();
int x = me.getX();
int y = me.getY();
Point location = source.getLocationOnScreen();
x += location.x;
y += location.y;
updateImage(x, y);
}
}
}
}
I'm aware of at least one accessibility helper in Windows that zooms in on the desktop as you move the mouse, but I've found it a bit intrusive. In so far as the app always takes up a big chunk of the desktop, where as I really only wanted the zooming feature for this window.
Enjoy!
Warning: I'm sure there are performance issues with this code on slower/older machines. As this isn't for production and was only needed in testing, I did no testing other than on my machine. If you're to incorporate something like this in a real app do performance analysis first!
- Login or register to post comments
- Printer-friendly version
- zixle's blog
- 848 reads





