JComponent ein- und ausfaden

mjkraus

Mitglied
Leider hilft mir die Lösung bei meinem aktuellen Problem nicht weiter, da ich nur einzelne Components faden möchte. :(
 

zerix

Hausmeister
Moderator
Okay. Cool, Danke!
Kannst du mir auch beim Ersetzen des Graphics-Objektes helfen?

Warum möchtest du denn das Graphics-Objekt ersetzen? Ich hab verstanden was du machen möchtest, aber nicht was du mit Graphics-Objekt ersetzen meinst. Da bringt es nichts wenn du mir nochmal zitierst, was du schon geschrieben hast. ;-)
Wenn du bei paintChildren, wie ich oben geschrieben habe, eine if-Anweisung reinpackst und den super-Aufruf in dieser hast, kannst du das Zeichnen der Kind-Objekte abschalten.

Code:
protected void paintChildren(){

    if(showChildren)
        super.paintChildren();

}

Wenn showChildren == false, werden die Kind-Komponenten nicht gezeichnet. Da machst du dann einfach ein else und zeichnest dein Image.

Und damit das transparent wird, nimmst du wieder das AlphaComposite.

Am besten nimmst du dann noch ein TimingFramework, welches gut für Animationen ist und setzt da dann den Alpha-Wert für dein AlphaComposite runter.

Gruß

Sascha
 

mjkraus

Mitglied
Okay. Da hab ich dich wohl falsch verstanden. Sorry!

Ich hab mal folgendes ausprobiert:
Java:
protected void paintChildren(){ 

    if(showChildren)
        super.paintChildren();
    else{
        BufferedImage img = new BufferedImage(this.getWidth(), this.getHeight(),
                                              BufferedImage.TYPE_INT_ARGB);
        this.paintComponent(img.getGraphics());
        Graphics2D g2d = (Graphics2D) g;
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                                                    this.opacity));
        g2d.drawImage(img, null, 0, 0);
    }
   
}
Das Bild wird allerdings nicht so darüber gelegt, dass das alles darunter Liegende überzeichnet wird, sondern durchscheint. Deshalb wollte ich das in den anderen Posts vorher immer leeren, bevor ich das Bild zeichne. :)

Das Schrittweise verändern des Transparenz-Wertes habe ich so gelöst:
Java:
import java.util.Timer;
import java.util.TimerTask;
...
new Timer().schedule(new TimerTask(){

    @Override
        public void run(){
            comp.fade(duration, toOpacity);
        }
      
}, 2000);
Wäre da das Timing Framework (http://java.net/projects/timingframework) besser dafür geeignet?
 

zerix

Hausmeister
Moderator
Du musst das nicht leeren. Das geht auch nicht. Das wenn es neu gezeichnet wird ist das alte ja weg und da wird nicht einfach drüber gezeichnet sondern es wird komplett neu gezeichnet.

Du solltest das Image nicht in der paintChildren-Methode erstellen. Sondern unmittelbar vor dem Fade-Effekt. Dann musst du es da nur noch zeichnen.



Gruß

Sascha
 

mjkraus

Mitglied
Hallo!

Jetzt funktioniert das Faden! Danke! Bin mir bloß nicht ganz sicher, was Du du mit das Image "unmittelbar vor dem Fade-Effekt. Dann musst du es da nur noch zeichnen." genau meinst? Das habe ich aus deiner Anwort gemacht: :)
Java:
class FadingComponent extends Component{
  BufferedImage fade;
  boolean fading = false;
  float opacity = 1f;

  public void fade(final int duration, final float opacity){
    fade = new BufferedImage(getWidth(), getHeight(), 
                             BufferedImage.TYPE_INT_ARGB);
    paintComponent(fade.getGraphics());
    fading = true;
    
    final int fps = 25;
    new Timer().schedule(new TimerTask(){
      Component comp = FadingComponent.this;
      //Anzahl der Fading-Schritte
      int i = (int) ((float) duration/1000*fps);
      //Veränderung des Transparenz-Wertes pro Schritt
      float step = (opacity - comp.opacity) / i;
    
      @Override
      public void run(){
        i--;
        //setzen des Transparenz-Werts und neuzeichnen der Komponente
        comp.setOpaque(comp.opacity + step);  
        if(i <= 0){
          this.cancel();
          comp.fading = false;
        }
      }
      
    }, 0, duration/fps);
  }

  @Override
  public void paint(Graphics g){
    if(!this.fading)
      super.paint(g);
    else{
      Graphics2D g2d = (Graphics2D) g;
      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                                                  this.opacity));
      g2d.drawImage((Image) this.fade, 0, 0, null);
    }
  }

  @Override
  protected void paintChildren(Graphics g){
    if(!this.fading)
      super.paintChildren(g);
  }

}
 
Zuletzt bearbeitet:

zerix

Hausmeister
Moderator
Du hast genau das gemacht, was ich meinte. ;-)
Du hattest in deinem alten Code die Erstellung des Images in der paintChildren. Das sollte einfach da raus. Das Image solltest du erstellen und zeichnen lassen, kurz bevor der Fading-Effekt gestartet wird und so hast du es jetzt auch gemacht.

Gruß

Sascha
 

mjkraus

Mitglied
Okay. Endlich hab ich es hin bekommen. :) Danke für die Hilfe! Ich hab noch etwas dran rum gebastelt und das wäre meine Lösung für das "Fading-Problem":

Java:
class FadingComponent extends Component{
  private float opacity = 1f;

  public FadingComponent(){
    this.setOpaque(false);
  }

  public void setOpaque(float opacity){
    //Transparenz-Wert setzen & repaint()
  }

  public void fade(final int duration, final float opacity){    
    final int fps = 25;
    new Timer().schedule(new TimerTask(){
      FadingComponent comp = FadingComponent.this;      
      //Anzahl der Fadingschritte
      int i = (int) ((float) duration/1000*fps);
      //Veränderung des Tranparenzwertes pro Schritt
      float step = (opacity - comp.opacity) / i;
    
      @Override
      public void run(){
        i--;
        comp.setOpaque(this.opacity + step);
        if(i <= 0){
          this.cancel();
        }
      }  
    }, 0, duration/fps);
  }

  @Override
  public void paint(Graphics g){
    if(this.opacity < 1){
      BufferedImage img = new BufferedImage(this.getWidth(), this.getHeight(), 
                                            BufferedImage.TYPE_INT_ARGB);
      super.paint(img.getGraphics());
      
      Graphics2D g2d = (Graphics2D) g;
      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 
                                                  this.opacity));
      g2d.drawImage(img, null, 0, 0);  
    }else{
      super.paint(g);
    }
  }

}
 
Zuletzt bearbeitet:

Neue Beiträge