Something for the weekend
Improved Dock Panel and Coder Stupidity
When I first publish my dock example, it was implemented in a glass pane. Which is fine. I also went through some hoops with AWT listeners to stop it sucking all the events away from the component below. I wrote some event forwarders. I added listeners. I did a lot of stuff. The whole time something was niggling away at the back of my mind. It just shouldn't be this hard. It wasn't.

There is a magical method for each container, that can cause it to NOT hog mouse events. It simply dictates whether or not there is a component at a particular x,y co-ordinate. If there's not, Swing doesn't pass the mouse event on. After all, there's nothing there. Here it is (you can over-ride it)

public boolean contains(int x, int y);

That's it. If it returns false, then no events are passed on and the clicks fall through. I had started fiddling with this, but then stopped hitting a recursive dead end when I called getComponentAt(int x,int y) inside it. Of course, all I should have done is a little bit of work to implement my own getComponentAt() and I would have had my solution. Find out if there is something in the dock panel that isn't a spacer that's at that co-ordinate... if there's not return false and pretend it's got nothing to do with me.

Here's the implementation:

public boolean contains(int x, int y) {
Rectangle rect=new Rectangle();
//Have to implement our own componentAt here
for (Component comp : getComponents()){
rect=comp.getBounds(rect);
if (rect.contains(x,y)){
if (comp instanceof JSpacer){
mouseMoved(new Point(-1,-1));
return false;
}
return true;
}
}
//A little non-intuitive. If it's not over a normal component or a spacer, it's in the dock area
return true;
}

The final return true is a little bit tricky (it's after all like saying, I didn't find anything but yes send me the message). This stops the mouse going over little gaps causing a problem, in general, if it's over a spacer pretend I'm not there, otherwise consume the event. Doing this enabled me to remove the GlassPaneDock class entirely, and a WHOLE load of complexity went with it. It's also enabled me to do something else I wanted to, add the dock into a Frame's layered pane. This is useful because it means I can make things like combo-box drop downs and pop-up menus appear over it (play with the demo to make it happen if you wish). Which might be more appropriate in some cases. In the screen shot below see how the combo-box appears OVER the dock.

Layered Dock Pane

This "perfect" message handling has one problem, the mouse can still fall between the cracks of dock icons from time to time, but that's part of another tweak I'm working towards. For now, the usual web-start and source code update has been done!

webstart-small2

|