December 18, 2008 Leave a comment
I’m not a big fan of UML diagrams, but in this case I think it really helps to explain how Cacio works (and to recognize its beauty 😉 ).
Let me go from top to bottom and explain the parts that make up Caciocavallo:
- Swing: Everybody knows it. It is a universe of its own. Basically, it builds on AWT, is implemented in 100% Java, only uses so-called lightweight (non-native) components, has a lot of Look & Feel fluff, etc.
- AWT: Slightly less known than Swing, this dinosaur is the foundation of Swing. It provides another, so-called heavyweight set of widgets, that are usually implemented by the corresponding platform widgets, as well as the toplevel containers (windows, dialogs, frames). It’s still 100% Java, but talks to AWT peers…
- AWT peers: a set of interfaces that are used by AWT for the platform dependent parts. AWT doesn’t care who it talks to, as long as it provides the implementations for all the widgets in AWT. OpenJDK has two implementations of the peers, one for Win32, one for X11. If you happen to have a system that has all the required widgets and stuff available, this is the place to plug in. Caciocavallo is yet another one that helps for the cases where you don’t have native widgets.
- The Cacio peers is another set of peers for AWT. It implements all the widgets by using Swing for drawing and logic. The idea is that each AWT widget should live in its own window. This means we have the obvious toplevel windows plus nested windows for all the components and containers. This makes sure that the widgets behave as they should – heavyweight. However, this windowing behaviour is not implemented in the peers directly, but instead hides behind the PlatformWindow interface.
- PlatformWindow is an interface that provides all the windowing behaviour that we need for the AWT widgets and toplevels. It looks very similar to ComponentPeer aggregated with WindowPeer, but there are also some differences. The PlatformWindow implementation to be used for a widget is created by a PlatformWindowFactory that lives in the CacioToolkit. If you have a system that has no widgets, but supports (nestable) windows, you implement PlatformWindow and get all the AWT widgets for free.
- ManagedWindow is an implementation of PlatformWindow for the case where you don’t have any native support for windows, for example a plain framebuffer. It implements all the necessary windowing behaviour, including nested and overlapping windows in Java, and builds only on another interface ManagedWindowContainer. Interestingly, it implements this same interface itself. This makes sense so that windows can be nested. ManagedWindows can also be useful on systems where you have support for toplevel windows, but not for nested windows. All you need to do is to implement the ManagedWindowContainer for the topmost container (e.g. the screen or the native toplevel windows).
- ManagedWindowContainer is a really small interface, it only has a handful of methods, the most important beeing getGraphics(). If you implement this correctly (e.g. the example PlatformScreen class in the diagram), you can serve everything that builds on it – you get windows, you get heavyweight widgets, and of course all the heavyweight and lightweight AWT/Swing stuff.
To summarize, there are 3 points to plug in potential implementations: at the peer level for systems with full widget sets, on the PlatformWindow level for systems w/o widgets but with windows or on the ManagedWindowContainer level for bare bones systems w/o anything. It’s also possible to start a full implementation on ManagedWindowContainer and then work the way up, because the interfaces are similar and higher-level interfaces are more or less supersets of the lower-level interfaces (it should be possible to transform a ManagedWindowContainer into a PlatformWindow, and to transform a PlatformWindow into a ComponentPeer and WindowPeer, etc). To give you a feel of the size: ManagedWindowContainer has ~4 methods, PlatformWindow ~20 methods, the whole set of peer interfaces ~100 methods.
Of course, this overview leaves out a lot of details, but in general it’s that easy. The implementation is not complete though: the peers don’t support all the widgets yet, the managed window doesn’t support every feature yet (i.e. restacking), but the general architecture is in place now, and it will most likely only change in the details.