JPanel setOpacity

Hallo.
Für JFrames gibt es ja die methode setOpacity(float f), um das fenster
transparent zu zeichnen; geht das auch irgendwie anders für JPanels oder andere Components?

Ich brauche Bilder, also kann ich nicht einfach Color(r g b a) verwenden, und auch nicht ein einzelnes
transparentes Bild nehmen weil das ganze animiert sein soll… Ich will halt ein und aus faden. Für ein JFrame hab ich das so:

public void fadeOut(JFrame f){
	for(int i = 50; i > -1; i--){
		f.setOpacity((float) (i) / 50);
	}
}
//ja, das ganze ist so lahm das ich kein Thread.sleep() brauche...

Vielen Dank!

Geht mit einem JPanel nicht ganz so einfach.
Um dies auch für ein Panel umzusetzen, musst du das Zeichnen des Bildes selbst übernehmen (Was du vermutlich schon machst) und davor einen Composite setzen.
Alles notwendig dazu dürfte folgender Link: http://www.informit.com/articles/article.aspx?p=26349&seqNum=5 erklären, der übrigends der erste Treffer bei Google war.

Die Methode mit der Schleife dürfte ohne sleep allerdings nicht mehr funktionieren, da AWT mehrere Aufrufe von repaint einfach Gnaden los zu einem zusammenlegt, wenn sie schnell hintereinander passieren. Dies würde dann wahrscheinlich dazu führen, dass kein einziger Zwischenschritt angezeigt wird.

Oh das hatte ich nicht gefunden, sry.
Werde es morgen mal probieren :slight_smile:
Schade das es nicht auch einfach mit swing geht.

Willst du den Panel-Hintergrund ein- und ausblenden? Oder Bilder halbtransparent übereinander legen? Ich habe das noch nicht so ganz verstenden.

ein und ausblenden.
Es geht mir halt generell darum ein JPanel transparent zu machen.

LeX’s Frage zielte wohl darauf ab, WAS auf diesem Panel zu sehen ist: Nur etwas selbstgezeichnetes oder ein Bild, oder ist das ein normales Panel mit normalen unter-Components drauf?

Für den allgemeinen Fall könnte man bei einem Panel die paint-Methode überschreiben (ja, ausnahmsweise paint und nicht paintComponent) und dann GROB sowas machen wie

    @Override
    public void paint(Graphics gr)
    {
        Graphics2D g = (Graphics2D)gr;
        Composite composite = AlphaComposite.getInstance(
            AlphaComposite.SRC_OVER, 0.25f);
        g.setComposite(composite);
        super.paint(g);
    }

Die 0.25 ist dann eben die Opazität. (Ungetestet, nur aus einem Codestück, bei dem ich sowas ähnliches mache, bei Bedarf nochmal bescheid sagen)

hey danke, das hat super funktioniert :slight_smile:
Und was darauf zu sehen ist, ist ja jetzt auch egal, das klappt ja :wink:

Nur eine Frage: was bedeuten die ganzen variablen AlphaComposite.SRC_OVER, SRC_OUT, XOR, und so weiter, das gibts ja etliche… Irgendwie wurde ich aus der doc nicht schlau.

*** Edit ***

Sieht jetzt so aus:

	public void fade(){
		new Thread(new Runnable(){
			public void run(){
				switch(type){
					case 0: for(int i = 100; i > -1; i--){
								x = (float) i / 100;
								try{
									Thread.sleep(3);
								}
								catch(Exception e){
									
								}
								panel.repaint();
							} type = 1; break;
					case 1: for(int i = 0; i < 100; i++){
								x = (float) i / 100;
								try{
									Thread.sleep(3);
								}
								catch(Exception e){
									
								}
								panel.repaint();
							} type = 0; break;
				}
			}
		}).start();
	}

Danke! :slight_smile:

Wegen der Konstanten (SRC_OVER usw), zugegeben: Wenn ich die brauche, überlege ich, welche ich verwenden muss - aber die IST es dann meistens DOCH nicht, und dann probier’ ich einfach rum bis es passt :o :smiley: Eigentlich ist nicht schwer zu erfassen, was die MACHEN, aber man muss halt immer schauen, dass man wirklich den Effekt bekommt, den man will.

Die Dinger nennen sich „Porter Duff Rules“ (You can’t get enough of that wonderful Duff :D), die genauen Bedeutungen sind auf http://en.wikipedia.org/wiki/Alpha_compositing erklärt.

aha… irgendwie glaube ich das src_over das einzige ist das ich brauchen werde… naja :slight_smile:

Das doppelte Sleep mit try-catch schreit danach, in eine kleine Methode sleep(long milliseconds) ausgelagert zu werden.

danke für den hinweis :slight_smile:

@Crian : Das dachte ich auch erst, und ich hatte schon das EDIT geschrieben, aber … da müßte man noch mehr dazu schreiben.

Erstens sollte es

try
{
    Thread.sleep(duration);
}
catch (InterruptedException e)
{
    Thread.currentThread().interrupt();
    return;
}

lauten, zweitens könnte man auch überlegen, den try/catch-Block größer zu machen.

Und drittens erscheint das mit dem „switch(type)“ ohnehin ziemlich un-elegant. Die erste, naheliegende Verallgemeinerung wäre

float min = 1-type;
float max = type;
float delta = max-min;
for (int i=0; i<=steps; i++)
{
    float alpha = (float)i/steps; // Ein Wert zwischen 0 und 1 (einschließlich)
    float currentValue = min + alpha * delta; // Ein wert zwischen min und max (einschließlich)
    ...
}

(Bei solchen Interpolations-Sachen ist es oft sehr hilfreich, erstmal so ein „alpha“ auszurechnen, das immer zwischen 0 und 1 interpoliert - das kann man dann i.a. sehr einfach und kanonisch auf andere Wertebereiche abbilden).

Weitere Verallgemeinerungen wären, nicht nur eine lineare Interpolation zuzulassen, aber… ja, man kann beliebig weit gehen :wink:

Aber da dieses faden eh nur eine drei viertel sekunde dauert ist mir das an der stelle egal xD
Das wäre dann wie in css ease-in ease-out und so weiter, das meinst du oder?