The Source for Java Technology Collaboration
User: Password:



Joshua Marinacci

Joshua Marinacci's Blog

Swing Hack 5: a magic lens

Posted by joshy on November 05, 2003 at 01:25 PM | Comments (3)

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.

Enjoy:

- Joshua
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);
        frame.setGlassPane(glass);
        glass.setVisible(true);
    }

}


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();
                LabelGlassPane.this.repaint();
            }
        });
    }
    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);
            }
        }
    }
}

Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • Cool
    I haven't a clue what I'd use this for, but it sure is neat.

    Posted by: johnreynolds on November 06, 2003 at 09:25 AM

  • Clip bounds pedantry
    Just for pedantry, there's a slight mistake. I don't think it actually makes any difference, but still. The code restores Graphics' user clip bounds as the user clip area. It also sets the clip area, rather than intersecting. The lines:

    Rectangle clip = g.getClipBounds();
    g.setClip(this.x-16,this.y-16,32,32);

    are better as:

    Shape clip = g.getClip();
    g.clipRect(this.x-16,this.y-16,32,32);

    On the basis that it is less error-prone to create and chuck than modifiy and restore, I'd go further by creating a copy of the Graphics object to work with:

    Graphics clipG = g.create();
    try {
    clipG.clipRect(this.x-16, this.y-16, 32, 32);
    rPaint(root, clipG);
    } finally {
    clipG.dispose();
    }

    As for uses. Perhaps when dropping with a TransferHandler, showing the current value of that property for the component in the drop zone.

    Posted by: tackline on November 06, 2003 at 06:10 PM

  • wow power leveling
    wow powerleveling
    wow power leveling
    wow gold
    wow items
    feelingame.com
    wow tips
    Most Valuable WOW Power Leveling Service
    wow power leveling faq
    cheap wow power leveling
    wow power leveling
    wow powerleveling
    wow power lvl

    Posted by: wowleveling3 on December 13, 2007 at 07:03 PM





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds