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:
Moduleworkspace direkt in eine Bilddatei gerendert
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...
WeiterlesenAI und ML Android Basteln C und C++ Chaos Datenbanken Docker dWb+ ESP Wifi Garten Geo Go GUI Hardware Java Jupyter JupyterBinder Komponenten Links Linux Markdown Markup Music Numerik OpenSource PKI-X.509-CA Präsentationen Python QBrowser Rants Raspi Revisited Security Software-Test sQLshell TeleGrafana Verschiedenes Video Virtualisierung Windows Upcoming...
Nach der letzten losen Zusammenstellung (für mich) interessanter Links aus den Tiefen des Internet von 2026 folgt hier gleich die nächste:
WeiterlesenEine neue Version der sQLshell ist verfügbar!
WeiterlesenNach der letzten losen Zusammenstellung (für mich) interessanter Links aus den Tiefen des Internet von 2026 folgt hier gleich die nächste:
WeiterlesenManche 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.