Tor Norbye of SUN is exactly the sort of fellow I want on my team.
And if further proof is needed.
Tor Norbye of SUN is exactly the sort of fellow I want on my team.
And if further proof is needed.
Web continuations fascinate me, but alas I have no current project in which to work on them. So I try to keep up in my reading instead.
I ran across this lengthy post on the "abandoned session" problem by Blushish Coder, one of my favorite code bloggers. Meanwhile, I bide my time looking for the right project for proposing continuations.
Leo Simons has a useful post on how to organize unit tests for complex software. Included is a nifty chart which explains his post well. I feel chart envy setting in.
I've started on a largish Java project (4000+ classes) with a complex Swing UI front-end and have had difficulty working out just which class is in play for a given visual component.
Glass pane to the rescue.
To help me out, I've written a small debugging glass pane based on a universal right-click handler found on Google similar to the example provided in the Swing documentation.
Use is simple:
JFrame frame = ...; DebugGlassPane.setDebugGlassPaneOn(frame);
Now when you hover the mouse over a component in the content pane, up pops a tooltip identifying the class and instance name. If you want to change the displayed information, edit createTipText(Component)
.
The complete class:
public class DebugGlassPane extends JComponent implements MouseListener, MouseMotionListener { private final JLayeredPane layered; public static void setDebugGlassPaneOn(final JFrame frame) { final Component glass = new DebugGlassPane(frame); // Must be in this order frame.setGlassPane(glass); glass.setVisible(true); } public DebugGlassPane(final JFrame frame) { layered = frame.getLayeredPane(); addMouseListener(this); addMouseMotionListener(this); } public void mouseMoved(final MouseEvent e) { setToolTipText(createTipText(getChildUnderMouse(e))); redispatchMouseEvent(e); } public void mouseDragged(final MouseEvent e) { redispatchMouseEvent(e); } public void mouseClicked(final MouseEvent e) { redispatchMouseEvent(e); } public void mouseEntered(final MouseEvent e) { redispatchMouseEvent(e); } public void mouseExited(final MouseEvent e) { redispatchMouseEvent(e); } public void mousePressed(final MouseEvent e) { redispatchMouseEvent(e); } public void mouseReleased(final MouseEvent e) { redispatchMouseEvent(e); } private String createTipText(final Component c) { return "<html>Class: <b>" + c.getClass().getName() + "</b><br>Name: <i>" + c.getName(); } private void redispatchMouseEvent(final MouseEvent e) { final Component component = getChildUnderMouse(e); // E.g., popup menus if (component == null) return; // redispatch the event component.dispatchEvent( SwingUtilities.convertMouseEvent(this, e, component)); } private Component getChildUnderMouse(final MouseEvent e) { // get the mouse click point relative to the content pane final Point containerPoint = SwingUtilities.convertPoint(this, e.getPoint(), layered); return SwingUtilities.getDeepestComponentAt(layered, containerPoint.x, containerPoint.y); } }
Surprisingly, I had a difficult time finding such a class already coded up somewhere. It is quite handy for exploring the UI.
UPDATE: An important fix (already incorporated in the code, above). Say you have a menu bar. The current code throws a NullPointerException
. The problem is that all the work is relative to the content pane, but a JFrame
can have visual space which recieves mouse events but is not part of the content.
The fix is simple: change getChildUnderMouse(MouseEvent)
to work with the component from frame.getLayeredPane()
instead of frame.getContentPane()
. Sun has a good explanatory diagram and description making this point clear.