Dienstag, 7. April 2026

Vaadin SVG Integration Frameworks Compared

 Hervorragend! Das ist das typische „SVG-Voodoo“: none bedeutet für den Browser „hier ist nichts“, während transparent bedeutet „hier ist eine Glasplatte“.

Damit dein Reversi-Board jetzt richtig professionell funktioniert, gibt es noch einen wichtigen Kniff. Wenn du später Steine (circle) in die Felder legst, werden diese die Klicks auf die Felder blockieren, falls du nicht aufpasst.

Der Profi-Touch für das Board

Hier sind zwei Optimierungen, die dein Board stabil machen:

  1. Pointer-Events für Steine deaktivieren: Damit du immer das Feld (rect) klickst, auch wenn schon ein Stein darauf liegt.

  2. CSS-Hover: Damit der Spieler sieht, welches Feld er gerade anvisiert.

Java
// Im Loop für die Steine
Element stone = new Element("circle", "http://www.w3.org/2000/svg");
// ... Positionierung ...
stone.setAttribute("fill", "transparent"); // Start: Leer
// DAS HIER IST ENTCHEIDEND:
stone.getStyle().set("pointer-events", "none"); 
svg.appendChild(stone);

// Im Loop für die Felder (rect)
rect.setAttribute("fill", "transparent");
rect.getStyle().set("cursor", "pointer");
// Hover-Effekt per Java-Style (oder CSS Klasse)
rect.addEventListener("mouseover", e -> rect.setAttribute("fill", "rgba(255,255,255,0.1)"));
rect.addEventListener("mouseout", e -> rect.setAttribute("fill", "transparent"));

Kurze Frage zum Bundle-Fehler:

Sind die Fehlermeldungen bezüglich des MainLayout und VerticalLayout im Log verschwunden? Wenn die Seite jetzt wieder korrekt mit Styling (Lumo-Theme) geladen wird, hat sich dein Bundle beim Neustart vermutlich selbst geheilt.

Falls das Layout immer noch "nackt" aussieht (nur Text, keine Vaadin-Buttons sichtbar), müssten wir noch einmal kurz den mvn clean Weg gehen.

Soll ich dir als nächstes zeigen, wie du eine flüssige CSS-Animation einbaust, wenn ein Stein die Farbe wechselt (der typische Reversi-Flip)?

Oracle Join mit bedingten Typen

 Da getplantsformaterial in deinem SQL wie eine herkömmliche Funktion aufgerufen wird, kannst du denselben Weg nutzen wie bei einer Stored Procedure.

In Oracle sind Funktionen (FUNCTION) technisch gesehen fast identisch mit Prozeduren, was die Speicherung angeht. Nutze eine der folgenden Möglichkeiten:

1. Der schnellste Weg (DBMS_METADATA)

Dies liefert dir das komplette CREATE OR REPLACE FUNCTION... Statement inklusive der Logik.

SQL
SELECT DBMS_METADATA.GET_DDL('FUNCTION', 'GETPLANTSFORMATERIAL') FROM DUAL;

Hinweis: Falls die Funktion einem anderen User gehört, füge das Schema hinzu: GET_DDL('FUNCTION', 'GETPLANTSFORMATERIAL', 'SCHEMA_NAME').


2. Über die Source-Tabelle (falls du keine Rechte für DBMS_METADATA hast)

Hier liest du den Quellcode Zeile für Zeile aus dem Data Dictionary:

SQL
SELECT text 
FROM all_source 
WHERE name = 'GETPLANTSFORMATERIAL' 
  AND type = 'FUNCTION'
ORDER BY line;

3. Was, wenn die Funktion Teil eines Packages ist?

In größeren Umgebungen sind solche Logiken oft in Packages gekapselt (z.B. PACKAGE_NAME.getplantsformaterial). In deinem SQL-Query oben sieht es zwar nach einer Standalone-Funktion aus, aber falls die obigen Abfragen nichts liefern:

  1. Prüfe, ob es ein Synonym oder ein Package gibt.

  2. Suche nach dem Package-Body, falls die Funktion dort definiert ist:

    SQL
    SELECT DBMS_METADATA.GET_DDL('PACKAGE_BODY', 'NAME_DES_PACKAGES') FROM DUAL;
    

Ein kleiner Tipp zur Fehlersuche:

Da die Funktion in deinem UNION ALL Block in einer CASE-Anweisung verwendet wird:

SQL
WHEN ps.Plant IS NULL THEN getplantsformaterial (m.oid)

... könnte es sein, dass sie bei großen Datenmengen die Performance bremst (da sie pro Zeile aufgerufen wird). Wenn du den Code hast, kann man oft sehen, ob man die Logik nicht direkt über einen Join effizienter lösen kann.

Soll ich dir beim Analysieren des Codes helfen, sobald du ihn mit GET_DDL ausgelesen hast?