Offscreen Rendering für Moduleworkspaces

Es ist nicht ganz einfach, eine Hierarchie von Swing-Komponenten offscreen zu rendern. Ich wollte aber genau dies für meine zentrale Komponente moduleworkspace umsetzen, die zum Beispiel die Grundlage für Lösungen wie den Visuellen Abfrageeditor in der sQLshell oder dWb+ darstellt.

Die eigentlich wichtige Information für erfolgreiches offscreen-Rendering von Swing-Komponenten ist: So lange sie nicht wenigstens einmal dargestellt wurden, ist ihre Eigenschaft visible=false. Weiterhin wichtig zu wissen ist, dass diese Eigenschaft nicht in der Hierarchie vererbt wird: Diese Eigenschaft eines Containers zu ändern führt nicht dazu, dass diese Eigenschaft an den enthaltenen Komponenten ebenfalls geändert wird.

Weiterhin ist es wichtig zu wissen, dass die Komponenten initial alle eine Breite und Höhe von 0 Pixeln haben. Daher werden sie zunächst nicht dargestellt, wenn man ein offscreen-Rendering versucht. Man kann das ändern, indem man die Größe explizit mittels setSize ändert oder sich auf die automatischen Layoutmechanismen von Swing verlässt und einfach doLayout aufruft. Auch hierbei gilt: diese Methode setzt die Größe der Komponente allein - in einem - Container wird dadurch diese Methode nicht an den enthaltenen Kind-Komponenten aufgerufen.

Mit diesen Erkenntnissen entstand diese Methode:

private static void ensureVisibility(java.awt.Component comp)
{
    comp.setVisible(true);
    comp.doLayout();
    if (java.awt.Container.class.isAssignableFrom(comp.getClass()))
    {
        java.awt.Container container = (java.awt.Container) comp;
        java.awt.Component[] com = container.getComponents();
        for (java.awt.Component co : com)
        {
            ensureVisibility(co);
        }
    }
}

Und damit kann man einen Modulworkspace dann in einen beliebigen GraphicsContext rendern:

workspace.setSize(800, 600);
java.awt.image.BufferedImage bimg = new java.awt.image.BufferedImage(800, 600, java.awt.image.BufferedImage.TYPE_INT_ARGB);
java.awt.Component[] comps = workspace.getComponents();
for (i = 0; i < comps.length; ++i)
{
    ensureVisibility(comps[i]);
}
workspace.setVisible(true);
workspace.drawNavigableRepresentation((java.awt.Graphics2D) bimg.getGraphics());
javax.imageio.ImageIO.write(bimg, "png", new java.io.File("/tmp/te.png"));

Das Ergebnis sieht dann wie folgt aus:

Screenshot Moduleworkspace direkt in eine Bilddatei gerendert

Alle Artikel rss Wochenübersicht Monatsübersicht Codeberg Repositories Mastodon Über mich home xmpp


Vor 5 Jahren hier im Blog

  • Trojan Source mit SQL und Postgres

    12.11.2021

    Nachdem ich das hochinteressante Paper Trojan Source: Invisible Vulnerabilities gelesen hatte kam ich durch einen Post auf Mastodon (leider nicht öffentlich einsehbar) auf Ideen... auf Ideen...

    Weiterlesen

Neueste Artikel

  • LinkCollections 2026 XIII

    Nach der letzten losen Zusammenstellung (für mich) interessanter Links aus den Tiefen des Internet von 2026 folgt hier gleich die nächste:

    Weiterlesen
  • sQLshell Version 7.9pre5 build 11394

    Eine neue Version der sQLshell ist verfügbar!

    Weiterlesen
  • LinkCollections 2026 XII

    Nach der letzten losen Zusammenstellung (für mich) interessanter Links aus den Tiefen des Internet von 2026 folgt hier gleich die nächste:

    Weiterlesen

Manche nennen es Blog, manche Web-Seite - ich schreibe hier hin und wieder über meine Erlebnisse, Rückschläge und Erleuchtungen bei meinen Hobbies.

Wer daran teilhaben und eventuell sogar davon profitieren möchte, muss damit leben, daß ich hin und wieder kleine Ausflüge in Bereiche mache, die nichts mit IT, Administration oder Softwareentwicklung zu tun haben.

Ich wünsche allen Lesern viel Spaß und hin und wieder einen kleinen AHA!-Effekt...

PS: Meine öffentlichen Codeberg-Repositories findet man hier.