# Transparenz



## Rainbow (3. Feb 2010)

Hi,
ich arbeite mit den AWTUtilities, um quasi ein rundes Fenster hinzubekommen.
Mein problem dabei ist jedoch das das total unschön aussieht.


```
AWTUtilities.setWindowShape(meinWindow, meinShape);
```

so schneid das ja ab, meinShape ist dabei eine Ellipse2D.Double.
Aber ich möchte gerne, das das alles eine Linie aussen herum ist und momentan sieht man halt jeden Pixel...gibt es eine Möglichkeit, das ich irgendwie einen schönen geraden Kreis hinbekommen ohne die Ecken und Kanten zu sehen?
...wenn man drawOval macht siehts ja auch schön rund aus.

Liebe Grüße


----------



## Landei (3. Feb 2010)

Keine Ahnung, ob das hilft, aber du könntest versuchen, die RenderingHints auf Antialiasing zu setzen:


```
//Für AWT-Komponente
public void paint(Graphics g) {
   antialiasing(g);
   super.paint(g);
}
//Für Swing-Komponente
public void paintComponent(Graphics g) {
   antialiasing(g);
   super.paintComponent(g);
}
private antialiasing(Graphics g) {
   ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
}
```

[edit]
Hier sind weitere Einstellungen, mit denen du das Zeichnen beeinflussen kannst:
Controlling Rendering Quality (The Java™ Tutorials > 2D Graphics > Advanced Topics in Java2D)


----------



## Rainbow (3. Feb 2010)

das hatte ich schon drin und bringt nichts...


----------



## njans (5. Jul 2011)

Ich möchte dieses Thema mal wiederbeleben, denn ich suche ebenfalls nach eine guten Möglichkeit ein rundes Fenster zu glätten.
Offen für Ideen und Lösungen


----------



## Dit_ (5. Jul 2011)

ich glaube mit Java 8 gibt es viele neue Funktionen um Form des Fensters (inkl. Transparenz) beliebig zu gestalten.

Oder schau dir das mal an Translucent and shaped windows in core Java  Pushing Pixels


----------



## Rainbow (5. Jul 2011)

Dit_ hat gesagt.:


> ich glaube mit Java 8 gibt es viele neue Funktionen um Form des Fensters (inkl. Transparenz) beliebig zu gestalten.
> 
> Oder schau dir das mal an Translucent and shaped windows in core Java  Pushing Pixels




das Problem bei den Beispielen bei dem Link ist einfach, das das ja so geht, aber der äußere rand nicht glatt ist...man hat dabei halt keinen schönen abgerundeten Kreis zum Beispiel...


----------



## njans (5. Jul 2011)

Ja, da hatte ich schon geschaut. Auch die Referenzen auf der Seite habe ich mir angeschaut.
Nun habe ich jedoch nichts funktionierendes gefunden, was die harten Kanten von ShapedWindos verschwinden lässt.
Und das ist ja äußerst schade.
Vielleicht hat jemand ein explizites codeschnipsel oder einen Link zu ner Lösung?
Im Anhang kann man wunderbar sehen, wie hart die Kanten auf einen weißen Desktop aussehen.


----------



## hansmueller (5. Jul 2011)

Hallo,

bei den Komentaren zu Translucent and shaped windows in core Java  Pushing Pixels wird bzgl. der Glättung der Kanten auf diesen Link verwiesen: Soft clipping and per-pixel translucency for Swing windows  Pushing Pixels

Auf dieser Seite dürfte dieser Link interessant sein: Java 2D Trickery: Soft Clipping | Java.net

MfG
hansmueller


----------



## njans (5. Jul 2011)

Genau den hatte ich auch getestet nur so, wie es da beschrieben steht, funktioniert es definitiv nicht.
Vielleicht mache ich da ja auch nur was falsch, aber das würde mich an der Stelle wundern, denn wenn das Überschreiben von paintComponent mit dem Beispiel genauso wenig funktioniert wie das Überschreiben von paint, dann weiß ich nicht, wo da der Fehler liegen sollte.


----------



## Rainbow (5. Jul 2011)

Das hab ich persönlich noch nicht getestet..ich probier das mal heute Abend aus und wenn es klappt, dann schreib ich das nochmal so wie ichs gemacht hab.


----------



## Ariol (5. Jul 2011)

Bei mir funktioniert die Verwendung von SrcAtop. Hier mal ein Minimalbeispiel:

```
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class CircleTest {

	public static void main(String[] args) {
		JFrame f = new JFrame();
		JPanel p = new JPanel(){
			protected void paintComponent(Graphics g) 
			{
				// Clear the background to black
				g.setColor(Color.BLACK);
				g.fillRect(0, 0, getWidth(), getHeight());

				// Create a translucent intermediate image in which we can perform
				// the soft clipping
				GraphicsConfiguration gc = getGraphicsConfiguration();
				BufferedImage img = gc.createCompatibleImage(getWidth(), getHeight(), Transparency.TRANSLUCENT);
				Graphics2D g2 = img.createGraphics();

				// Clear the image so all pixels have zero alpha
				g2.setComposite(AlphaComposite.Clear);
				g2.fillRect(0, 0, getWidth(), getHeight());

				// Render our clip shape into the image.  Note that we enable
				// antialiasing to achieve the soft clipping effect.  Try
				// commenting out the line that enables antialiasing, and
				// you will see that you end up with the usual hard clipping.
				g2.setComposite(AlphaComposite.Src);
				g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
				g2.setColor(Color.WHITE);
				g2.fillOval(getWidth()/4, getHeight()/4, getWidth()/2, getHeight()/2);

				// Here's the trick... We use SrcAtop, which effectively uses the
				// alpha value as a coverage value for each pixel stored in the
				// destination.  For the areas outside our clip shape, the destination
				// alpha will be zero, so nothing is rendered in those areas.  For
				// the areas inside our clip shape, the destination alpha will be fully
				// opaque, so the full color is rendered.  At the edges, the original
				// antialiasing is carried over to give us the desired soft clipping
				// effect.
				g2.setComposite(AlphaComposite.SrcAtop);
				g2.setPaint(new GradientPaint(0, 0, Color.RED, 0, getHeight(), Color.YELLOW));
				g2.fillRect(0, 0, getWidth(), getHeight());
				g2.dispose();

				// Copy our intermediate image to the screen
				g.drawImage(img, 0, 0, null);

			};
		};
		f.add(p);
		f.pack();
		f.setVisible(true);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
	}
	
}
```


----------



## njans (5. Jul 2011)

Ariol du hast wohl den Thread nicht ganz gelesen 
Ein Bild zu zeichnen und das dann mit nem RenderingHint zu smoothen ist auch kein Problem.
AWTUtilities.setWindowShape(meinWindow, meinShape);

Das resultierende Window soll gerundete Ecken haben.


----------



## Ariol (6. Jul 2011)

Schuldig...

Das eine Beispiel sieht doch ganz gut aus: Soft clipping and per-pixel translucency for Swing windows  Pushing Pixels

Kann das hier nicht wirklich testen, weil Java unter Linux wohl Probleme mit transparenten Fenstern hat. Ich versuch's evtl morgen nochmal.


----------



## njans (6. Jul 2011)

Ja das sieht auch okay bei RoundRectangle aus, aber ne Ellipse sieht so aus, wie mein Anhang.
Und das ist ja furchtbar! Also ich denke mal schon, dass ich an dem Beispiel code einfach was falsch mache, soll ja anscheinend direkt mit dem setWindowShape im Zusammenhang stehen aber ich habe keine Ahnung, was ich da falsch machen ^^


----------



## Rainbow (6. Jul 2011)

Also mein Problem, als ich das Thema gestartet hab war ja, das der innere Kreis zwar schön abgerundet ist...aber das, was ich abschneide eben nicht. Das sieht einfach nicht schön gerundet aus...da helfen die Links auch nicht weiter.
Also genau das, was dieser Teil macht:

```
if((AWTUtilities.isTranslucencySupported(AWTUtilities.Translucency.TRANSLUCENT))) {
			AWTUtilities.setWindowShape(_dialog, createShape());
		}
```


----------



## Landei (6. Jul 2011)

Erinnert mich an Salvodor Dali:






Spiegelei ohne Teller


----------



## Ariol (6. Jul 2011)

Versuchs doch mal so:
Shape dein Window als Kreis. Ein paar Pixel größer als er eigentlich sein sollte.
Setze den Hintergrund auf transparent.
Zeichne darauf einen Kreis, der nicht bis zu Rand des Windows geht (entsprechend mit Antialiasing und Co).

Damit sollte das sichtbare einen glatten Rand bekommen.
So ähnlich ist das auch in dem Beispiel gemacht.


----------



## Rainbow (6. Jul 2011)

klingt vernünftig


----------



## njans (6. Jul 2011)

Witzig! Als ich heute nen Kommilitonen gefragt habe, hatte er die selbe Idee, deswegen habe ich das auch schon getestet und kann sagen: Es geht!
Hier mal mein Code 

setWindowOpaque ist wichtig, damit das ganze Fenster auch als Transparent angezeigt werden kann.

```
AWTUtilities.setWindowShape(this, new Ellipse2D.Double(0, 0, this.getWidth(), this.getHeight()));
AWTUtilities.setWindowOpaque(this, false);
```

Die Seize habe ich hier um 4 Pixel verkleinert, da einer dann doch leicht ekig war. So bekommt man einen deutlich runderen Kreis!

```
// Set the size to a smaller value to give the antialiasing a little space 
		int width = this.getWidth() -4;
		int height = this.getHeight() -4;

		// Create a new graphics object to fill the background with a transparent color
		Graphics2D graph = (Graphics2D)g.create();
		graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0f));
		graph.fillRect(0, 0, this.getWidth(), this.getHeight());
		
		// Create a new graphics object that paints on a BufferedImage
		GraphicsConfiguration gc = ((Graphics2D)g).getDeviceConfiguration();
		BufferedImage img = gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
		Graphics2D graph2 = img.createGraphics();
		
		// Set the renderingHint to create a smooth oval
		graph2.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
		
		// *******************************************************
		// Draw as you like in this section
		
		graph2.setColor(Color.black);
		graph2.fillOval(0,0, width, height);
		
		// *******************************************************
		// Set the composite back to visible and than draw the BufferedImage onto the translucent background
		graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));
		graph.drawImage(img, 2, 2, null);
		
		// Dispose of the used grapic objects
		graph.dispose();
		graph2.dispose();
```


----------



## Landei (6. Jul 2011)

Oh mein Gott, der Schwarze Fleck!!!1Elf!


----------



## Rainbow (7. Jul 2011)

Ok,bei mir funktioniert das jetzt auch...sieht gut aus. :toll:


----------



## njans (7. Jul 2011)

Dann kannst du wohl den Thread als erledigt markieren!


----------

