Skip to content

AWT Peer Implementation

Levente Santha edited this page May 11, 2026 · 4 revisions

AWT Peer Implementation

JNode implements AWT peers using Swing components as a lightweight simulation of a desktop operating system, bypassing the need for a host OS windowing system.

Overview

Unlike traditional JVMs that delegate UI rendering to the host OS (X11, Windows), JNode implements the entire peer layer from scratch. The peer implementation uses Swing components as an internal rendering backend, creating a simulated desktop environment that draws directly to the framebuffer.

Key Components

Class Location Purpose
JNodeToolkit gui/src/awt/org/jnode/awt/JNodeToolkit.java Base toolkit, bridges AWT to framebuffer
SwingToolkit gui/src/awt/org/jnode/awt/swingpeers/SwingToolkit.java Creates all peer instances using Swing
JNodeGraphicsEnvironment gui/src/awt/org/jnode/awt/JNodeGraphicsEnvironment.java Manages screen devices and fonts
AWTPlugin gui/src/awt/org/jnode/awt/AWTPlugin.java Plugin lifecycle management
DesktopFrame gui/src/awt/org/jnode/awt/swingpeers/DesktopFrame.java Root window (the desktop)
DesktopFramePeer gui/src/awt/org/jnode/awt/swingpeers/DesktopFramePeer.java Peer for desktop
JNodeEventQueue gui/src/awt/org/jnode/awt/JNodeEventQueue.java Event dispatch
KeyboardHandler gui/src/awt/org/jnode/awt/KeyboardHandler.java Raw keyboard to AWT events
MouseHandler gui/src/awt/org/jnode/awt/MouseHandler.java Mouse input handling

Architecture

Initialization Flow

Boot → AWTPlugin.startPlugin()
     → VMImageUtils.setAPI(new VMImageAPIImpl())
     → Application calls Toolkit.getDefaultToolkit()
     → JNodeToolkit.incRefCount() initializes graphics mode
     → JNodeToolkit.onInitialize() (abstract, implemented by SwingToolkit)
     → SwingToolkit creates DesktopFrame

Toolkit Hierarchy

java.awt.Toolkit
    └── gnu.java.awt.ClasspathToolkit (GNU Classpath)
            └── org.jnode.awt.JNodeToolkit (abstract base)
                    └── org.jnode.awt.swingpeers.SwingToolkit

Peer Creation Pattern

When an AWT component is created, the toolkit creates a peer:

// Example from SwingToolkit.java
protected ButtonPeer createButton(Button target) {
    return new SwingButtonPeer(this, target);
}

Each peer wraps a Swing component that handles rendering. The peer maps between AWT and Swing coordinate systems and event models.

How It Works

Framebuffer Integration

JNode connects to video hardware through the Video-Driver-Architecture:

  1. JNodeToolkit queries DeviceManager for FrameBufferAPI implementations
  2. Requests ownership of the framebuffer via api.requestOwnership(this)
  3. Opens a Surface for drawing: api.open(config.getConfig())
  4. All painting operations write directly to video memory

Desktop Frame

The DesktopFrame is the root of the component hierarchy:

// From SwingToolkit.onInitialize()
desktopFrame = new DesktopFrame(getScreenSize());
desktopFrame.show();
desktopFrame.getContentPane().repaint();

All other AWT Frames are rendered as JInternalFrames inside this desktop's JDesktopPane.

Event Handling

Input Hardware → KeyboardHandler/MouseHandler
              → JNodeEventQueue
              → EventQueue.dispatchEvent()
              → AWT Component event listeners

The KeyboardHandler and MouseHandler convert hardware interrupts into AWT events:

  • Keyboard scancodes → KeyEvent (KEY_PRESSED, KEY_RELEASED, KEY_TYPED)
  • Mouse movement/clicks → MouseEvent (MOUSE_MOVED, MOUSE_DRAGGED, MOUSE_CLICKED, etc.)

Peer Interfaces

Swing peers implement standard AWT peer interfaces:

Peer Interface Implementation
ButtonPeer SwingButtonPeer
LabelPeer SwingLabelPeer
FramePeer SwingFramePeer / DesktopFramePeer
WindowPeer SwingWindowPeer
ContainerPeer SwingContainerPeer
LightweightPeer SwingLightweightPeer
... ...

Each implementation wraps the corresponding JComponent and delegates painting, event handling, and layout.

Font Rendering

JNode includes a TrueType font subsystem:

  • TTFFontPeer — wraps a TrueType font file
  • FontManager — service managing available fonts
  • TextRenderer — renders glyphs to graphics context

Font rendering flows through the graphics pipeline to the framebuffer.

SwingFramePeer and DesktopFrame

The SwingFramePeer (lines 54-167 in SwingFramePeer.java) implements FramePeer and ISwingContainerPeer. It wraps a SwingFrame (an internal JInternalFrame subclass) and manages:

  • Window state (iconified, maximized, normal)
  • Menu bar integration via setMenuBar()
  • Addition to the desktop via addToDesktop()

The DesktopFrame (lines 45-165 in DesktopFrame.java) extends JFrame and implements JNodeAwtContext. It serves as:

  • The root window containing all other AWT windows
  • A JDesktopPane that manages internal frames
  • Background color persistence via Preferences
  • Size adjustment through adjustDesktopSize()

Threading Model

The peer implementation uses SwingToolkit.invokeNowOrLater() to ensure thread-safe operations:

// From SwingFramePeer.java
public void setMenuBar(final MenuBar mb) {
    SwingToolkit.invokeNowOrLater(new Runnable() {
        public void run() { /* ... */ }
    });
}

This ensures AWT operations execute on the Event Dispatch Thread (EDT) while handling cases where peers may be created from different AppContext instances.

Gotchas

  • No native windowing: AWT windows are simulated internally; they don't correspond to OS-level windows
  • Reference counting: GUI mode uses incRefCount()/decRefCount() to track active users; when count reaches zero, graphics are released
  • AppContext isolation: Peers must be created in the same AppContext as the desktop frame to ensure event dispatch works correctly
  • Look and feel: SwingToolkit sets MetalLookAndFeel with OceanTheme as default
  • Desktop ownership: The first Frame created becomes the desktop; subsequent frames become internal frames

Related Pages

Clone this wiki locally