Swing Hack 5: a magic lens

It's been a while since I've written something, so I thought I'd start out with another Swing Hack. This time I've expanded on the overlay idea of SwingHack 3 by adding sort of a magic lens. In this hack the overlaid information can only be seen when the special lens cursor is over it. To pull this off I've created a custom cursor using a buffer image and set it on the glasspane. The buffer contains a crude set of boxes to define the view area, but you could just as easily use an image of a magnifying lens. Next I've restricted the drawing of the glass pane to only be under the cursor by getting the cursor coordinates from a mouse motion listener and setting a clipping rectangle centered around the cursor. Finally I've added code to print the mouse coordinates as part of the cursor. Run, compile, and you get this: (pretend that you can see the cursor which Windows printscreen thoughtfully removes for you)

Note, I could have put the box drawing code into the glasspane instead of the cursor, but I wanted the corners of the lens box to be visible when the mouse is slightly out of the window.


import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.awt.image.*;public class MagCursor { /* steps for this new hack create bitmap w/ mag glass on it set custom cursor do overlay drawing of dimensions �� restrict drawing based on cursor location (clip rect) */ public static void main(String[] args) { BufferedImage img = new BufferedImage(32,32,BufferedImage.TYPE_INT_ARGB_PRE); Graphics g = img.getGraphics(); g.setColor(Color.blue); g.drawRect(0,0,31,31); g.drawRect(15,15,2,2);
Point hotspot = new Point((int)(16),(int)(16)); Toolkit tk = Toolkit.getDefaultToolkit(); Cursor cursor = tk.createCustomCursor(img,hotspot,"JoshyMag"); JFrame frame = new JFrame("frame"); frame.getContentPane().add("North",new JButton("button")); frame.getContentPane().add("South",new JTextField("textfield")); frame.getContentPane().add("Center",new JTextArea(3,20)); frame.getContentPane().add("East",new JLabel("label")); frame.getContentPane().add("West",new JPasswordField("password")); frame.pack(); frame.show(); LabelGlassPane glass = new LabelGlassPane(frame); glass.setCursor(cursor);

class LabelGlassPane extends JComponent {
public JFrame frame;
public int x, y;
public LabelGlassPane(JFrame frame) {
this.frame = frame;
this.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseMoved(MouseEvent evt) {
x = evt.getX();
y = evt.getY();

public void paint(Graphics g) { g.setColor(Color.red); Container root = frame.getContentPane(); Rectangle clip = g.getClipBounds(); g.setClip(this.x-16,this.y-16,32,32); rPaint(root,g); g.setClip(clip); } private void rPaint(Container cont, Graphics g) { for(int i=0; i<cont.getComponentCount(); i++) { Component comp = cont.getComponent(i); if(!(comp instanceof JPanel)) { int x = comp.getX(); int y = comp.getY();
int w = comp.getWidth(); int h = comp.getHeight(); g.setColor(new Color(100,100,100,100)); g.drawRect(x+4,y+4,w-8,h-8); g.drawString(comp.getClass().getName(),x+10,y+20); g.setColor(new Color(255,0,0,100));
g.drawString(this.x + "," + this.y, this.x-16,this.y-5); } if(comp instanceof Container) { rPaint((Container)comp,g); } } }}
Talk to me about it on Twitter

Posted November 5th, 2003

Tagged: java swing-hacks java.net