2D-Grafik Schattenwurf (Drop-Shadow) für Fenster

kceenav

Mitglied
Guten Tag!

Auf der Suche nach einer Möglichkeit, JAVA-Fenstern einen schicken Schatten zu verpassen, bin ich auf die Seite Java 2D - Drop Shadow On JInternalFrame gestoßen. Dort will jemand den "ShadowRenderer" von Guy Romain zum selben Zweck verwenden, der nicht nur für Leser von dessen Buch "Filthy Rich Clients" zugänglich ist. ;)

Mithilfe ebendieser Klassen "ShadowRenderer" sowie der ebenfalls verfügbaren "GraphicsUtilities" und mittels Zeichnen auf eine ganz außen liegende "EmptyBorder" ist es mir auch gelungen, ein paar selbst dekorierten Dialog-Fenstern einen recht effektvollen Schattenwurf mitzugeben. Perfekt ist das Resultat zwar meiner Meinung nach noch nicht, da der Schatten bislang "nur" unterhalb und rechts vom Fenster geworfen wird, aber das lässt sich ja vielleicht noch ändern (falls jemand weiß, wie ... ?).

Im Moment habe ich mich mit diesem Punkt nicht weiter befasst, weil es zuvor ein sehr viel wichtigeres Problem zu lösen gilt, soll das Ganze auch für den normalen praktischen Gebrauch taugen:

Wie veranlasst man, dass beim Verschieben des Fensters ein neuer, für den geänderten Hintergrund passender Schatten erzeugt wird?

Hier zunächst einmal die entscheidende Code-Stelle, wie ich sie der genannten Web-Seite entnommen habe:
Java:
    @Override
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g.create();
        int w = getWidth();
        int h = getHeight();

        if (shadow == null || shadow.getWidth() != w || shadow.getHeight() != h) {
            // recreate shadow if frame size changed
            BufferedImage frameImg = GraphicsUtilities.createCompatibleTranslucentImage(
                    w - 2 * SHADOW_WIDTH, h - 2 * SHADOW_WIDTH);
            super.paint(frameImg.createGraphics());
            shadow = shadowRenderer.createShadow(frameImg);
        }

        g2.drawImage(shadow, 0, 0, null);

        // Motif ALMOST honors the empty internal frame border
        // comment this line out to see interesting artifacts in Motif LaF
        g2.setClip(0, 0, w - 2 * SHADOW_WIDTH, h - 2 * SHADOW_WIDTH);
        super.paint(g2);
        g2.dispose();
    }

Offensichtlich muss man anlässlich eines Verschiebevorgangs obige paint-Methode zum Einsatz bringen, was ja auch nicht schwierig ist. Die Frage, wie häufig man diesen wohl ziemlich aufwendigen -- und auch zeitaufwendigen -- Prozess, so ein Schatten-(Buffered-)Image (= 'shadow') zu erzeugen, anstoßen kann/darf, soll erst mal unwichtig sein.

Woran es im Augenblick hakt, ist, dass es mir nicht gelingt, den jeweils neuen Schatten mit den NICHT (vom bereits existierenden Schatten) verdeckten Pixeln des Hintergrunds zu "verschmelzen". Was stattdessen passiert: Mit jeder Neu-Berechnung des Schattens wird dieser dunkler -- soweit ich das verstehe deshalb, weil eben der für die Berechnung maßgebliche Ausschnitt des Hintergrunds nach dem ersten Mal nicht mehr "jungfräulich" ist, sondern vom bereits vorhandenen Schatten, tja, überschattet ...

Wer weiß da Abhilfe?
 

Marco13

Top Contributor
So ganz ist (mir) die Frage jetzt nicht klar geworden... aber irgendwo dieses BufferedImage erstmal leer machen, mit einem Rectangle mit Color (0,0,0,0) und einem passenden Composite so dass der bisherige Inhalt übermalt wird...?!
 

kceenav

Mitglied
Der Schattenwurf funktioniert und ist wirklich sehr effektvoll. Leider ist er mit dieser Methode wohl nur mit Fenstern machbar, die man "undecorated" erzeugt, bei denen man also selbst für ein (auch sonst) ansehnliches Aussehen mit Rahmen und ggf. Titelleiste samt "Widgets" sorgt.

Die Frage lautet: Ist es irgendwie möglich, so ein Fenster MIT(!) Schatten "normal" verschiebbar zu machen? (Ohne dass die Illusion dabei zerplatzt, selbstverständlich.)

Ich habe mich seither viel mit dem "Problem" (eher eine Spielerei ...) beschäftigt. Und nach jeder Menge Rumprobiererei ist mir schließlich die Erkenntnis gedämmert, dass dies mit dem bisher verwendeten Verfahren, bei dem der Schatten auf eine ganz außen (außerhalb des sichtbaren Randes/Rahmens) liegende "EmptyBorder" gezeichnet wird, prinzipiell nicht möglich ist.
Grund: Die EmptyBorder scheint bloß transparent zu sein, ist es aber gar nicht. Wenn kein anderer Container drunter liegt, wird zwar in ihrem Bereich nicht wirklich ge-painted. Sie nimmt aber sozusagen bei der Sichtbarmachung des Fensters die Pixel an, die bis dahin zum Hintergrund gehört haben.

Bewegt man anschließend das Fenster, werden die vermeintlich "leeren" Rahmen sofort sichtbar, weil die einmal angenommene, perfekt mit dem Hintergrund verschmolzene "Tarnung" nur für die ursprüngliche Position vor dem Hintergrund 100%ig passt. (Es sei denn, der Hintergrund wäre großflächig monochrom und strukturlos ...) Ob dabei noch der Schatten darüber gezeichnet wurde, spielt gar keine Rolle.

Ein Workaround wäre vielleicht, die EmptyBorder zwischendurch wegzunehmen, damit das Betriebssystem bzw. Swing dazu veranlasst werden, den Bereich neu zu zeichnen, der für unsere erlernte räumliche Wahrnehmung "dahinter" zu liegen scheint. (Wird er nämlich nicht "von Grund auf" neu gezeichnet, existiert er faktisch einfach nicht mehr, außer eben für die menschliche Vorstellung.)
Das habe ich auch versucht; es ist mir aber nicht gelungen, dass das Fenster bei der Entfernung des "Leer"-Rahmens nicht DEUTLICH SICHTBAR nach links-oben springt (da ich den Schatten auch ein wenig links und oberhalb des Fensters haben wollte, dort also auch einen Rahmen hatte).

Bei Gelegenheit will ich noch mal versuchen, den (Dialogfenster-)Schatten auf die GlassPane eines "darunter" liegenden, sehr viel größeren Hauptfensters zu zeichnen, in der Hoffnung, dass dessen temporäre Löschung dort leichter handhabbar ist. Keine Ahnung, ob das überhaupt klappen kann und wie schwierig das ist ...
 

Wildcard

Top Contributor
Du solltest die Window Decorations dem Window Manager des Betriebssystems überlassen. Was soll zB passieren wenn der Windows Manager bereits Drop Shadows für Fenster zeichnet? Vielleicht sogar in einer anderen Farbe?
Würde irgendwie dämlich aussehen, oder?
 

kceenav

Mitglied
Hallo,

derartige Überlegungen sind mir bereits selbst gekommen. Auch deshalb schrieb ich zuletzt ja von einer "Spielerei". :)

Welche Betriebssysteme bieten denn diese Schatten-Option? Bei Vista/7 habe ich kürzlich das erste mal darauf geachtet, dort war einer vorhanden, der allerdings nicht im Entferntesten an die Qualität des von mir gerade ausprobierten ShadowRenderer herankommt.
Ist der Schatten dann womöglich auch noch an-/abschaltbar?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Drag und drop aus einer JTable - bitte um Unterstützung AWT, Swing, JavaFX & SWT 2
G JPanel per Drag and Drop JButtons und Bilder ablegen AWT, Swing, JavaFX & SWT 1
AmsananKING ListView Drag And Drop AWT, Swing, JavaFX & SWT 0
AmsananKING Drag And Drop Filenames Inside A Listview AWT, Swing, JavaFX & SWT 1
DonBronson Java Graphics bewegbar machen (Drag&Drop) AWT, Swing, JavaFX & SWT 3
M Polygon per Drag&Drop verschieben AWT, Swing, JavaFX & SWT 26
Z Swing Drag and Drop mit einem JButton AWT, Swing, JavaFX & SWT 1
S Drop Target Instanzprüfung AWT, Swing, JavaFX & SWT 6
N Drag and Drop Fenster AWT, Swing, JavaFX & SWT 11
F Drag&Drop mit Transparenter Farbe bei PNG AWT, Swing, JavaFX & SWT 0
D JavaFX Pane per Drag&Drop bewegen? AWT, Swing, JavaFX & SWT 2
L JavaFX Drag and Drop funktioniert nicht AWT, Swing, JavaFX & SWT 3
J Drag and Drop von eigenen Objekten AWT, Swing, JavaFX & SWT 3
J Drag and Drop eines Buttons AWT, Swing, JavaFX & SWT 0
T Swing Drag and Drop für JComponents AWT, Swing, JavaFX & SWT 1
Z Swing Drag&Drop zwischen JTable und JTree AWT, Swing, JavaFX & SWT 4
F Drag und Drop AWT, Swing, JavaFX & SWT 0
L JavaFX JavaFX Chart Drag and Drop AWT, Swing, JavaFX & SWT 3
D JavaFX Drag&Drop mehrerer TreeViews oder TableViews AWT, Swing, JavaFX & SWT 1
P Drag & Drop zwischen Panels AWT, Swing, JavaFX & SWT 0
U Drag and Drop mit imageview AWT, Swing, JavaFX & SWT 0
U Drag and Drop imageviews AWT, Swing, JavaFX & SWT 8
D SteelSeries in Netbeans als Drag-and-Drop einbinden AWT, Swing, JavaFX & SWT 0
C JTable Drag and Drop von Zeilen innerhalb einer Table AWT, Swing, JavaFX & SWT 2
S Swing Update eine JTabelle nach einer Drag&Drop Operation AWT, Swing, JavaFX & SWT 0
S Swing Suche Drag & Drop Beispiele AWT, Swing, JavaFX & SWT 1
A Drag and Drop mit JAVAFX- Scenebuilder AWT, Swing, JavaFX & SWT 1
R Performance Drag and Drop & Timer AWT, Swing, JavaFX & SWT 3
R Drag and Drop Problem auf Jpanel AWT, Swing, JavaFX & SWT 2
N Swing JTable und Drag und Drop AWT, Swing, JavaFX & SWT 2
A Drag and Drop eigener Objekte AWT, Swing, JavaFX & SWT 7
C Drag and Drop (inventar) AWT, Swing, JavaFX & SWT 15
F Swing Drag and Drop in JTree aus verschiedenen Listen AWT, Swing, JavaFX & SWT 6
T Swing JButton per Drag&Drop verschieben AWT, Swing, JavaFX & SWT 5
S SWT: Drop-Down Menü-Einträge mit Tooltip hervorheben AWT, Swing, JavaFX & SWT 3
Iron Monkey JFileChooser - Drag and Drop AWT, Swing, JavaFX & SWT 5
Iron Monkey Nach Drag & Drop die Datei auf Komponent darstellen AWT, Swing, JavaFX & SWT 2
M AWT Drag n Drop-Support für Component AWT, Swing, JavaFX & SWT 5
HaukeG Swing Drag & Drop in verschiedenen Varianten AWT, Swing, JavaFX & SWT 4
S Swing Drag&Drop mit TransferHandler und JPanels AWT, Swing, JavaFX & SWT 8
C Swing Simulation von Drag and Drop Events AWT, Swing, JavaFX & SWT 3
H Swing "Drag and Drop" eines JComponent über ein JPanel AWT, Swing, JavaFX & SWT 2
R Drag 'n Drop AWT, Swing, JavaFX & SWT 3
Daniel_L Drop von Dateien auf Frame - welche Drop-Location? AWT, Swing, JavaFX & SWT 2
L SWT Drop erfolgreich, aber GUI-Aktion abgebrochen AWT, Swing, JavaFX & SWT 4
G SWT TreeViewer - drop listener austauschen AWT, Swing, JavaFX & SWT 2
S Selektion bei Drag&Drop AWT, Swing, JavaFX & SWT 4
C Swing Drag and Drop mit Objekten in einem Fenster. AWT, Swing, JavaFX & SWT 9
T SWT Drag&Drop: Eclipse FileTransfer mit Icons AWT, Swing, JavaFX & SWT 14
F Drag & Drop durch Verbindungslinien AWT, Swing, JavaFX & SWT 10
T Swing Drag and Drop - JLabels tauschen statt überschreiben AWT, Swing, JavaFX & SWT 11
S Drag and Drop über 2 Panels AWT, Swing, JavaFX & SWT 2
K JButtons innerhalb eines JPanels verschieben (DRAG&DROP) AWT, Swing, JavaFX & SWT 5
B Drag and Drop AWT, Swing, JavaFX & SWT 6
K Drag and Drop Workbench AWT, Swing, JavaFX & SWT 2
P SWT Eclipse Draw2D Drag and Drop (ruckelt) AWT, Swing, JavaFX & SWT 4
T Swing JFileChooser --> Desktop und Laufwerke im "Suchen in" - Drop Down AWT, Swing, JavaFX & SWT 3
F SWT Drag and Drop im TreeViewer AWT, Swing, JavaFX & SWT 4
B Swing Drag&Drop mit Feedback (Image am Mauszeiger) AWT, Swing, JavaFX & SWT 7
P [JTree] Markierhilfe der Drop-Location selber gestalten. AWT, Swing, JavaFX & SWT 4
Spin JFrame/ Frame Drag and Drop AWT, Swing, JavaFX & SWT 13
A TransferHandler & Drag n' Drop AWT, Swing, JavaFX & SWT 2
R Drag an Drop JTable Zelle AWT, Swing, JavaFX & SWT 6
D Drag & Drop - node.isRoot AWT, Swing, JavaFX & SWT 3
E Swing Drag n Drop Verschieben von Labels o.ä. AWT, Swing, JavaFX & SWT 10
E Swing Beim Drag & Drop, Drag verbieten?! AWT, Swing, JavaFX & SWT 2
E JTree Autoscroll bei Drag and Drop AWT, Swing, JavaFX & SWT 4
F Swing Problem mit Drag&Drop in JTable AWT, Swing, JavaFX & SWT 4
C keine weiteren Events während Drag&Drop Operation möglich? AWT, Swing, JavaFX & SWT 5
E Drag&Drop zwischen 2 Listen AWT, Swing, JavaFX & SWT 5
0 Swing Drag n' Drop Bug wenn Source und Target gleiche Komponente? AWT, Swing, JavaFX & SWT 4
C Drag and Drop JPanel auf JPanel nach drop erneut verschieben? AWT, Swing, JavaFX & SWT 3
M Swing JTable Drag'n'Drop von Dateien AWT, Swing, JavaFX & SWT 3
M Drag and Drop: Quellfenster AWT, Swing, JavaFX & SWT 2
M Buttons per Drag & Drop im GridBagLayout verschieben AWT, Swing, JavaFX & SWT 6
M Swing JList > Drag & Drop AWT, Swing, JavaFX & SWT 2
C Drag an Drop vom JTree zur JTable AWT, Swing, JavaFX & SWT 4
Z Drag and Drop auf Application AWT, Swing, JavaFX & SWT 3
G Drag and Drop JTree to Canvas AWT, Swing, JavaFX & SWT 7
H Drag&Drop von JComponents AWT, Swing, JavaFX & SWT 6
G JTable drag and drop AWT, Swing, JavaFX & SWT 4
H Drag&Drop mit GWT AWT, Swing, JavaFX & SWT 8
hdi SWT JComboBox : Drop-Down Header ohne Eintrag AWT, Swing, JavaFX & SWT 6
B Swing Drag&Drop einzelner Zellen in einer JTable AWT, Swing, JavaFX & SWT 12
A Swing Drag and Drop TreeNode User Object AWT, Swing, JavaFX & SWT 3
P JList: Reihenfolge der Elemente per Drag'n'Drop ändern. AWT, Swing, JavaFX & SWT 9
K Swing Wie ändere ich die default action für Drag&Drop AWT, Swing, JavaFX & SWT 6
R JLayeredPane - Drag&Drop - mouseDragged AWT, Swing, JavaFX & SWT 6
C JTable mit RowSorter und Drag & Drop: Zeile verschieben AWT, Swing, JavaFX & SWT 4
V SWT TreeViewer Drag'n'Drop LocalSelectionTransfer AWT, Swing, JavaFX & SWT 10
R Swing JLayeredPane - Drag&Drop Positionen vertauschen AWT, Swing, JavaFX & SWT 3
F Drag & Drop mit eigenen Komponenten AWT, Swing, JavaFX & SWT 2
B SWT - Drag & Drop innerhalb einer Table AWT, Swing, JavaFX & SWT 3
S Drag'n'Drop AWT, Swing, JavaFX & SWT 8
E Drag&Drop JTable; Renderer füllt alle Zellen AWT, Swing, JavaFX & SWT 10
M Drag & Drop in Swing (createTransferable) AWT, Swing, JavaFX & SWT 6
T Drag Quelle beim Drop AWT, Swing, JavaFX & SWT 6
A Drag & Drop von Zeilen innerhalb einer Tabelle AWT, Swing, JavaFX & SWT 2
E Drag & Drop von jTree in JList AWT, Swing, JavaFX & SWT 5
P Dateien per Drag&Drop ins Java-Fenster ziehen AWT, Swing, JavaFX & SWT 8

Ähnliche Java Themen

Neue Themen


Oben