Overlap Layout
Posted by Rob Camick on July 26, 2009
All the layout managers, that I’m aware of, position components in a separate area of a container. This makes sense as you generally don’t want components to overlap one another. However, there may situations, in a card game for example, where it is reasonable to have components overlapping one another. I haven’t played with the ZOrder support that was added in JDK5, but I figured this might be a way to support overlapping components.
Sure enough using the ZOrder makes the code of an overlapping layout relatively easy,
although it took me a little while to understand how ZOrdering works. The API simply says that components with a higher ZOrder are painted before components with a lower ZOrder. However, the ZOrder is not really a property of a component. The ZOrder is actually defined by the components placement in the container. As you add components A, B and C to a container the components are assigned a ZOrder of 0, 1, 2 respectively. When you iterate through the container you get the components back in the order you added them, which is A, B, C. However, if the ZOrder of component C is changed to 0, then the components position in the container is altered. That is, if you now iterate through the container you get components C, A, B. So changing the ZOrder of a single component can affect other components as well. Until I realized this the layout code wasn’t working as expected.
Anyway, enough about how ZOrder works. The end result of this effort is the OverlapLayout, which hopefully is straight forward to use. First you need to specify whether a component should be painted “above” or “below” the previous component. The default is to paint components above one another. Next you need to specify the overlapping position of each component. A Point object is used to control the overlap position. By specifying different x, y values you can achieve various layout effects:
- x, 0 – left-to-right layout
- -x, 0 – right-to-left layout
- 0, y – top-to-bottom layout
- 0, -y – bottom-to-top layout
- x, y – diagonal top/left-to-bottom/right layout
- -x, y – diagonal top/right-to-bottom/left layout
- x, -y – diagonal bottom/left-to-top/right layout
- -x, -y – diagonal bottom/right-to-top/left layout
- 0, 0 – a “stack” layout. Components are stacked on top of one another.
The following code was used to create the left-to-right OverlapLayout used in the image below:
OverlapLayout layout = new OverlapLayout(new Point(20, 0));
layout.setPopupInsets(new Insets(20, 0, 0, 0));
JPanel panel = new JPanel( layout );
panel.add(card1);
panel.add(card2);
...
Now I guess I need to explain what the popup insets are used for. This is a feature that was specifically added to support card games. In some games you may want a selected card to stand out from the rest. This can be achieved by having the card “popup”. Therefore we need to reserve extra space in the container to allow room for the component to popup. The component will popup in the direction that has been allocated extra space. The popup state of a component is controlled by a contraint:
- POP_UP – the component is painted in the popup position
- POP_DOWN (or null) – the component is painted in the normal position
A MouseListener was added to each card in the Web Start demo. The code to toggle the popup state of the component is as follows:
public void mousePressed(MouseEvent e)
{
Component c = e.getComponent();
Boolean constraint = layout.getConstraints(c);
if (constraint == null || constraint == OverlapLayout.POP_DOWN)
layout.addLayoutComponent(c, OverlapLayout.POP_UP);
else
layout.addLayoutComponent(c, OverlapLayout.POP_DOWN);
c.getParent().invalidate();
c.getParent().validate();
}
The OverlapLayout works similiar to the GridLayout in that the components are all set to be the same size as determined by the maximum width or height of any given component added to the container. An exception to this is when components are “stacked”. In this case all components are sized to the area of the container.
In general, the OverlapLayout has only been tested using JLabels. I did notice that when using JButtons, mouse entered events caused the overlapped button to be painted on the top other buttons, resulting in confusing rendering of each component. If you have this problem then the solution is to override the isOptimizedDrawingEnabled() method of the JPanel to return false. This tells the repainting subsystem that components overlap so painting issues can be resolved properly.
Anyway, hopefully you can find some interesting uses for the OverlapLayout, whether it be for a card game or something else.
Try The Demo
– Using Java™ Web Start (JRE 6 required)

Alejandro Fernandez said
Can you include the source code for the demo?
Rob Camick said
Sorry for taking so long to reply. The source code doesn’t show how to use the class. The example code in the blog is all you need to add this class to your program. However, I have included the test code as part of the OverlayLayout.jar file which you can download and then extract the code.
Mr. NO said
Can you supply link to the OverlapLayout.jar?
Mr. NO said
Nevermind. Here it is: http://www.camick.com/java/webstart/overlaplayout.jar
Mr. NO said
I cannot get the panel to show unless I add it to a JScrollPane before I add it to the frame. How come? What am I missing?
OverlapLayout layout = new OverlapLayout(new Point(20, 0));
layout.setPopupInsets(new Insets(20, 0, 0, 0));
JPanel panel = new JPanel( layout );
panel.add(card1);
panel.add(card2);
...
JFrame frame = new JFrame("Card game");
frame.add(new JScrollPane(panel)); //Works
frame.add(panel); //Does not work for me, nothing shows.
Rob Camick said
You should not need to add the panel to a scrollpane. Do your “cards” actually have a preferred size that the layout manager can use? If you need more help then use the “Contact Us” page and post a SSCCE so we can take the discussion offline.
Benny said
“Hi Rob Camick, I was wondering if my team could use your code for a project we are designing? We are creating the Hearts card game for our class and this helps a lot for overlapping the cards. Thank you for your time.”
Rob Camick said
As the About page says: “You are free to use and/or modify any or all code posted on the Java Tips Weblog without restriction.”