Alright so I went with the approach in my second reply and got this working beautifully. Each time I drag the component (mouseDragged event) I:
1) make the component being dragged invisible
2) get that components top level container and use the findComponentAt method with a converted mousePoint to find the highest visible component underneath the component I just made invisible
3) set that highest component as the target component
4) then make the dragged component visible again.
This allows me to drag and reposition JPanels on top of other JPanels!!!
Now I'm trying to expand my program to include JSplitPanes as well but I'm running into problems.
My previous solution worked like this:
1) The mouseDragged() method is given a mouseEvent as an argument. This mouseEvent contains a point which is calculated as the difference between the position of the mouse cursor and the top left corner of where the JPanel is DRAWN.
2) Next I moved the JPanel about by using the mouseEvent's point and translating the BOUNDS of the JPanel using setBounds().
3) The next time the JPanel is drawn, its BOUNDS are referenced and it is DRAWN accordingly.
4) Return to step 1.
This solution does not work when I am trying to drag a JPanel that is the child of a JSplitPane. In step 3, the bounds of the JPanel are ignored because the JPanel is restricted to reside within the JSplitPane. I don't mind that the JPanel is restricted there, the problem is that the bounds are used when the mousePoint is converted to the coordinate system of the topLevelContainer. If the bounds dot not correspond to where the component is drawn, it will not correctly determine the cursor's location.
While I was typing this problem up I poked around the API and managed to find a solution (below).
I fixed this by using getLocation() and setLocation() instead of getBounds() and setBounds(). I believe that bounds are a component preference (like size) and not a component rule. When I call setLocation() on a JPanel that is a child of a JSplitPane, neither the location nor the bounds of the JPanel change because the JSplitPane won't allow it.
Why it works:
Originally both the bounds of the JPanel and where it was being drawn were changing together, so the bounds correctly referenced the drawing location. With the JSplitPane the bounds were being changed but the drawing location was not, so there were errors. By using setLocation() we have ensured that the bounds will not change unless the drawing location does so again, they will correspond to each other and we get rid of our errors.
Another problem I found in my old code is that I was translating the JPanel's location before converting the mousePoint to the coordinate system of the top level container. This caused the mouse's movement to be counted twice.