Ideas about improved architecture of the generic Swing peers

Roman Kennke roman.kennke at aicas.com
Fri Aug 15 03:09:52 PDT 2008


Hello people,

I'd like to outline my ideas about an improved architecture of the
generic Swing based peers. But let me first describe the current state
and the problem(s) we need to address:

Currently, the Swing peers implement most of the peers in
java.awt.peer.* (well ok, minus a couple of complex ones, like
ScrollPane, Choice, etc). They are not supposed to work standalone, but
need some support by a real backend. Most notably, this would be an
implementation of java.awt.Toolkit and the top-level window peers
(WindowPeer, DialogPeer and FramePeer). Based on these toplevel windows,
the Swing peers handle all the widgets in a semi-lightweight fashion:
all the drawing is done using Graphics contexts from the toplevel
windows. However, the actual Swing components are not connected to the
component hierarchy in any way, they are only 'hooked in' in a way, so
that from the perspective of the Swing component it appears as if it
were in the component hierarchy, but infact it isn't (from the
perspective of the hierarchy).

This architecture, requiring the real backend to implement the toplevel
windows, and do everything else in a quasi-lightweight fashion has some
disadvantages, or at least, one big disadvantage. It is really hard to
get the special behaviour of AWT heavyweight components correct. For
example, suppose you have a Frame, inside this frame you have a Swing
component, and a Panel. The panel would always be on top of the Swing
component, regardless of the stacking order in the window. To make it
even more complex, if you had a Swing component in the Panel, it would
be drawn on the Panel, not on the Window (an thus, it would appear to be
always on top of the other Swing component). To get this right in the
Swing peers, we had to implement a bunch of hacks, that involve double
buffers for all components and other ugly stuff, and it never worked
really well.

The answer, for me, was found in the implementation of the XWindow peers
in OpenJDK. All AWT components are 'simply' given their own X Windows.
I, coming from a Swing background, first had to get over this concept a
little, but then it seemed all logical, and I think most toolkits (at
least in the X world) are implemented like that. And even though not
specified exactly, Java AWT applications expect such behavior from AWT
components.

What I would like to propose is a kind of blend between the architecture
of the XAWT peers in OpenJDK and the Swing peers: Let all AWT components
be drawn in their own window, but let Swing do the drawing and handling
of logic and events. This way, we would get a maximum portable AWT peer
implementation, that requires only minimal effort to port to any new
platform. The interesting part is to implement this idea:

The first thing to think about is that all components should have their
own window. To me, this means, that the common superclass of all the
peers, the SwingComponentPeer, must implement all the necessary
windowing behaviour. This is done similarily in the XAWT peers, but in a
very X specific way. All other peers, including the toplevel peers and
the widgets, derive from this class (an exception would probably be the
menu related peers). Since SwingComponentPeer already implements all the
necessary windowing functionality, the toplevel peers don't have much to
do on their own, except delegating to super here and there. The widget
peers now don't search for a parent graphics for drawing, but can do
everything in their own window.

The tricky part here is, when the SwingComponentPeer is at the top of
the hierarchy, how can we 'plug in' platform specific code there?
Subclassing surely isn't it. My idea is to have a kind of PlatformWindow
interface, which is used by the SwingComponentPeer to delegate all the
real window implementation stuff to. We should be careful to create a
nice clean interface there. Porting the AWT would then be as simple as
implementing this one interface (plus J2D pipeline), and boing! have all
the AWT widgets and toplevel windows available.

And we need to consider that not only SwingComponentPeer calls into the
PlatformWindow impl, but the PlatformWindow impl also needs to call back
to the SwingComponentPeer for handling events. In the XAWT
implementation this is done by passing back X events. Of course, we
don't want platform specific events in the Swing peers. So the
PlatformWindow implementation needs to take care and transform all
platform specific events to Java AWT events before passing them back to
the SwingComponentPeer. It might be necessary to introduce a couple of
internal peer events for handling stuff that is not covered by the
'official' AWT events.

Summary of the architecture outline (this would be a good point to slip
in an UML diagram, but I really don't like diagrams ;-) ):

SwingComponentPeer is the all-mighty master superclass here. It provides
all the necessary windowing functionality. But it doesn't implement this
itself, but instead delegates to a PlatformWindow implementation.
PlatformWindow would be an interface that specifies all the windowing
functionality that we need from the underlying platform. The
PlatformWindow implementation is also expected to pass all the events
from the window to the SwingComponentPeer, in the form of AWT event
objects (it must already translate the native event types to the
corresponding AWT events). Subclasses of SwingComponentPeer implement
both the widgets as well as the toplevel windows. Drawing the widgets
and handling the state logic of the component is done by Swing.

Please tell me what you think.

Cheers, Roman

-- 
Dipl.-Inform. (FH) Roman Kennke, Software Engineer, http://kennke.org
aicas Allerton Interworks Computer Automated Systems GmbH
Haid-und-Neu-Straße 18 * D-76131 Karlsruhe * Germany
http://www.aicas.com   * Tel: +49-721-663 968-48
USt-Id: DE216375633, Handelsregister HRB 109481, AG Karlsruhe
Geschäftsführer: Dr. James J. Hunt




More information about the caciocavallo-dev mailing list