Class Graphics2DTestPlusGlassPane

java.lang.Object
  extended byGraphics2DTest
      extended byGraphics2DTestPlusUserDrawing
          extended byGraphics2DTestPlusGlassPane

public class Graphics2DTestPlusGlassPane
extends Graphics2DTestPlusUserDrawing

This is an extension of the Graphics2DTestPlusUserDrawing example that illustrates how to put a glass pane on the top of the window to pre-screen mouse events before they're sent through to the underlying components. As a simple example, all that happens here is the capture of a mouse pressed event with the right mouse button. Otherwise, all events are dispatched to the Components below.

The key to getting the glass pane to do the interception is two-fold: the glass pane must have setVisible set to true, AND there must be some kind of event listeners on the glass pane. There's also the obnoxious behavior noted below in the createAndShowGUI method about setVisible having to be called AFTER setGlassPane. This is indeed HIGHLY OBNOXIOUS, given that it's not documented anywhere I could find.

Once this is done, events have to be selectively dispatched down to underlying components, where "selectively" means the target component of the event must be determined, and passed the right kind of specialized event object. This is illustrated in the Sun Java tutorial on using glass panes, named GlassPaneDemo.java.

Another trick is that a specialized glass pane, typically in the form of a JComponent, must implement the kind of listeners that underlying components are looking for. E.g., in the GlassPaneDemo, the class MyGlassPane implements ItemListener, since it wants to forward item events down to an underlying checkbox. In this example, RightClickGlassPane implements ActionListener, so it can forward ActionEvents down to the three buttons on the bottom of the display screen.

The major work of event handling in this example is done in the redispatchEvent method in the RightClickListener class. This method converts the mouse event into a form the target object will like. In particular, the drawing canvas wants mouse events, whereas the buttons want Action events. For the canvas, the events are redispatched directly, after x/y coordinate normalization. For the buttons, redispatching an action event is a bigger pain than just calling the button listener's actionPerformed method, once the target button is in hand.

Adding to the messiness here is the fact that there is no addActionListener method on the JComponent that is serving as the glass pane, whereas there is an addMouseListener. Overall, things do get rather messy, given the highly diverse set of events that can be thrown at different types of components. There may be some generalizing high-level type of event or listener, but I couldn't find it.

This seems to hint at why the GlassPaneDemo is implemented the way it is. Viz., instead of trying to forward events to the underlying JButtons, it just turns the glass pane on and off, so that the button action events get sent straight through when the glass pane is off, rather than having MyGlassPane implement ActionEvent, as well as ItemEvent.

Anyway, I don't think there's a way to avoid at least some messiness, if not a lot of it, when it comes to forwarding events from a glass pane down to a variety of different types of underlying components.


Nested Class Summary
static class Graphics2DTestPlusGlassPane.RightClickGlassPane
          Class RightClickGlassPane defines the specialized JComponent that is installed as the glass pane object.
static class Graphics2DTestPlusGlassPane.RightClickListener
          Class RightClickListener implements all of the methods of a MouseInputAdapter.
 
Nested classes inherited from class Graphics2DTestPlusUserDrawing
Graphics2DTestPlusUserDrawing.RectDrawingListener, Graphics2DTestPlusUserDrawing.RectShapeUserDrawn
 
Nested classes inherited from class Graphics2DTest
Graphics2DTest.DrawingCanvas, Graphics2DTest.MousePressedListener, Graphics2DTest.RectShape
 
Field Summary
 
Fields inherited from class Graphics2DTestPlusUserDrawing
startX, startY
 
Fields inherited from class Graphics2DTest
addButton, buttonBox, canvas, delButton, frame, numButton, shapeList, vbox, x, y
 
Constructor Summary
Graphics2DTestPlusGlassPane()
           
 
Method Summary
protected static void createAndShowGUI()
          Method idea borrowed from GlassPaneDemo, for starting up an application in a thread-safe manner.
static void main(java.lang.String[] args)
          Do what super.main does (too bad we can't just call it), then set the frame's glass pane to the specialized one with the right-click listener.
 
Methods inherited from class Graphics2DTestPlusUserDrawing
changeDeleteButtonListener
 
Methods inherited from class Graphics2DTest
addButtonListeners, compose
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

Graphics2DTestPlusGlassPane

public Graphics2DTestPlusGlassPane()
Method Detail

main

public static void main(java.lang.String[] args)
Do what super.main does (too bad we can't just call it), then set the frame's glass pane to the specialized one with the right-click listener.


createAndShowGUI

protected static void createAndShowGUI()
Method idea borrowed from GlassPaneDemo, for starting up an application in a thread-safe manner. This code could just be put directly in the main method, but it's done this way as an illustration of an alternate form of application startup.