Transparentes Shape mit Schatten

Status
Nicht offen für weitere Antworten.
Hi!
Ich möchte ein Rechteck mit abgerundeten Ecken, Text und Schatten zeichnen. Soweit - sogut. Den Schatten kann man entweder manuell durch Zeichnen eines weiteren solchen Rechtecks (verschoben) oder einfach durch eine AffineTransform erzeugen.
Jetzt soll das Rechteck aber halbtransparent sein. Und hier beginnt das Problem: Die Transparenz kann man durch AlphaComposite erreichen, aber dann sieht man auch den Schatten durch und das soll nicht so sein.
Kann man das irgendwie verhindern?

Ich hoffe das war klar, ich habe leider keine Möglichkeit ein Bild hochzuladen. Vielleicht hilft auch der Code:

Code:
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.RoundRectangle2D;

import javax.swing.JComponent;


public class Test extends JComponent {

	private String text = "TEST";
	
	public Test() {
		super();
		setSize(200,200);
		setFont(new Font("Dialog",Font.PLAIN,20));
		setBackground(new Color(100,150,200));
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		Graphics2D g2 = (Graphics2D)g;
		
		g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING, 
                RenderingHints.VALUE_ANTIALIAS_ON);

		RoundRectangle2D.Float rect = new RoundRectangle2D.Float(
			10,
			10,
			100,
			100,
			25,
			25
		);
		
		g2.setPaint(new Color(0, 0, 0, 50));
		g2.fill(AffineTransform.getTranslateInstance(10, 10).createTransformedShape(rect));
		
		Stroke s = g2.getStroke();
		g2.setStroke(new BasicStroke(2));
		g2.setColor(Color.BLACK);
		g2.draw(rect);
		g2.setStroke(s);
		
//		g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.5f));
		
		g2.setColor(getBackground());
		g2.fill(rect);
		
		g2.setColor(getForeground());
		
        if(getFont() != null) {
        	FontMetrics fm = getFontMetrics(getFont());
            
        	g2.setColor(getForeground());
        	
        	g2.drawString(
    			text,
  		       (rect.width - fm.stringWidth(text))/2,
  		       (rect.height - fm.getHeight())/2
      		);
        }
	}
	
}
 

Marco13

Top Contributor
Ja, wenn's transparent ist, sieht man halt den Schatten durch .... das ist ja die Beduetung von "Transparent" ???:L

Wie auch immer: Man kann für das zeichnen des Schattens eine Clipping-Redion definieren, die das Zeichnen nur in Bereichen zuläßt, die außerhalb des eigentlichen Rechtecks liegen
Code:
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.RoundRectangle2D;

import javax.swing.*;
import java.awt.geom.*;
import java.awt.geom.Area;


public class ShadowRectTest extends JComponent {

   private String text = "TEST";


   public static void main(String args[])
   {
       JFrame f = new JFrame();
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       f.getContentPane().add(new ShadowRectTest());
       f.setSize(500,500);
       f.setVisible(true);
   }




   public ShadowRectTest() {
      super();
      setSize(200,200);
      setFont(new Font("Dialog",Font.PLAIN,20));
      setBackground(new Color(100,150,200));
   }

   @Override
   protected void paintComponent(Graphics g) {
      Graphics2D g2 = (Graphics2D)g;

      g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

      RoundRectangle2D.Float rect = new RoundRectangle2D.Float(
         10,
         10,
         100,
         100,
         25,
         25
      );

      g2.setPaint(new Color(0, 0, 0, 50));
      Area area = new Area(new Rectangle2D.Float(0,0,getWidth(),getHeight()));
      area.exclusiveOr(new Area(rect));
      g2.setClip(area);
      g2.fill(AffineTransform.getTranslateInstance(10, 10).createTransformedShape(rect));
      g2.setClip(null);

      Stroke s = g2.getStroke();
      g2.setStroke(new BasicStroke(2));
      g2.setColor(Color.BLACK);
      g2.draw(rect);
      g2.setStroke(s);

      g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.5f));

      g2.setColor(getBackground());
      g2.fill(rect);

      g2.setColor(getForeground());

        if(getFont() != null) {
           FontMetrics fm = getFontMetrics(getFont());

           g2.setColor(getForeground());

           g2.drawString(
             text,
               (rect.width - fm.stringWidth(text))/2,
               (rect.height - fm.getHeight())/2
            );
        }
   }

}
 
Marco13 hat gesagt.:
Ja, wenn's transparent ist, sieht man halt den Schatten durch .... das ist ja die Beduetung von "Transparent" ???:L
Dachte mir schon dass sowas kommt :D Mir ists klar, aber sag das mal den Auftraggebern und Grafikern :bae:

DANKE! Ist genau das was ich gesucht hab. Hab schon mit setClip herumgespielt, aber die 2 Zeilen hab ich nicht zusammenbekommen.
 

Marco13

Top Contributor
Richtig cool würde es aussehen, wenn man noch ein
Code:
      g2.setPaint(new Color(0, 0, 0, 25));
      g2.setClip(rect);
      g2.fill(AffineTransform.getTranslateInstance(10, 10).createTransformedShape(rect));
      g2.setClip(null);
davor macht: Dann sieht man einen "leichten" Schatten durch :cool:

Übrigens gut, dass du diese Frage gestellt hast. Ein ähnliches Problem hatte ich neulich auch, und bin nicht auf die Lösung gekommen :bahnhof: Jetzt müßt' ich's aber hinkriegen....
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben