O'Reilly logo

Swing Hacks by Chris Adamson, Joshua Marinacci

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

482
|
Chapter 12, Miscellany
#96 Debug Components with a Custom Glass Pane
HACK
Screens and Glass
The first step is to create a sample screen for the glass pane to draw on top
of, as seen in Example 12-17.
This
main( ) method creates a frame with a few components and one nested
panel (called
panel). The ComponentGlassPane is declared as a subclass of
JComponent so it can be passed to the setGlassPane( ) method on the frame.
The glass pane is not visible initially, which produces the same behavior as if
it wasn’t even there. The activate button is used to make the glass pane
visible.
The next step is to create the
ComponentGlassPane constructor:
Example 12-17. A screen for the glass pane
public class ComponentGlassPane extends JComponent {
public static void main(String[] args) {
JFrame frame = new JFrame("Component Boundary Glasspane");
Container root = frame.getContentPane( );
root.setLayout(new BoxLayout(root,BoxLayout.Y_AXIS));
final JButton activate =
new JButton("Show component boundaries");
root.add(activate);
root.add(new JLabel("Juice Settings"));
JPanel panel = new JPanel( );
panel.setLayout(new BoxLayout(panel,BoxLayout.X_AXIS));
panel.add(new JLabel("Flavor"));
panel.add(new JTextField(" "));
root.add(panel);
frame.pack( );
frame.show( );
final ComponentGlassPane glass =
new ComponentGlassPane(frame);
frame.setGlassPane(glass);
activate.addActionListener(new ActionListener( ) {
public void actionPerformed(ActionEvent evt) {
glass.setVisible(true);
}
});
}
Debug Components with a Custom Glass Pane #96
Chapter 12, Miscellany
|
483
HACK
private JFrame frame;
private Point cursor;
public ComponentGlassPane(JFrame frame) {
this.frame = frame;
cursor = new Point( );
this.addMouseMotionListener(new MouseMotionAdapter( ) {
public void mouseMoved(MouseEvent evt) {
cursor = new Point(evt.getPoint( ));
ComponentGlassPane.this.repaint( );
}
});
this.addMouseListener(new MouseAdapter( ) {
public void mouseClicked(MouseEvent evt) {
ComponentGlassPane.this.setVisible(false);
}
});
}
This method saves the parent frame that was passed in, and it creates a new
point to store the cursor coordinates. Then it adds two mouse listeners to
itself. The first listener copies the current mouse coordinates into the cursor
object every time the mouse moves. It also requests a repaint, since the user
may have moved from one component to another, which would change the
currently visible label.
The second mouse listener simply waits for mouse clicks. If the user clicks
the mouse, then this listener turns off the visualization effect by hiding the
glass pane, and the screen goes back to normal.
So far this has all been pretty straightforward: create a custom
JComponent
and set it as the glass pane on a JFrame. Now comes the tricky part: painting
the translucent rectangles and labels. First, you need to override the
paint( )
method to retrieve the root component of the frame and pass it to the
rPaint( ) method:
public void paint(Graphics g) {
Container root = frame.getContentPane( );
rPaint(root,g);
}
rPaint( ) stands for recursive paint. It needs to recurse over the entire com-
ponent tree, painting a rectangle at each step and possibly drawing the label.
Because this is so complicated, I’ll take it in stages. Here is the initial por-
tion of the method:
private void rPaint(Component comp, Graphics g) {
int x = comp.getX( );
int y = comp.getY( );
g.translate(x,y);
cursor.translate(-x,-y);

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required