2010-02-09 20 views
23

Ho una classe che eredita da JPanel con un'immagine su di essa e voglio impostare una piccola animazione per visualizzare il pannello/immagine e poi svanire quando un evento si attiva.Come si dissolve un'immagine in oscillazione?

Probabilmente presento un thread e spegni l'animazione, ma come faccio a fare la dissolvenza?

risposta

14

È possibile eseguire personalmente la filettatura, ma potrebbe essere più semplice utilizzare la libreria Trident per gestirla. Se crei un setter sulla tua classe chiamata (ad esempio, setOpacity), puoi chiedere al tridente di interpolare il campo "opacità" da 1.0 a 0.0 in un determinato periodo di tempo (qui è some of the docs su come utilizzare Trident).

Quando si dipinge l'immagine, è possibile eseguire la trasparenza con un AlphaComposite, utilizzando il valore di "opacità" aggiornato per il parametro alfa del composito. Esiste un tutorial su Sun che include uno alpha composite example.

+1

@Ash: +1, stavo andando a suggerire utilizzando AlphaComposite. – SyntaxT3rr0r

+0

Trident fa anche "attenuazione" dell'interpolazione? – blank

+0

Credo che faccia l'interpolazione lineare (principalmente?), Basata su questo post del blog dell'autore di Trident (secondo all'ultimo paragrafo): http://www.pushing-pixels.org/?p=1599 – Ash

6

Esistono alcune informazioni utili che descrivono la trasparenza dell'immagine here.

vostro approccio potrebbe essere qualcosa di simile:

  • Definire uno swing Timer di sparare un ActionEvent sul filo Evento spedizione ogni N millisecondi.
  • Aggiungi un ActionListener allo Timer che dovrebbe chiamare repaint() sul Component contenente il Image.
  • Override metodo s' il ComponentpaintComponent(Graphics) per effettuare le seguenti operazioni:
    • Fusioni l'Graphics oggetto a un Graphics2D.
    • Impostare un AlphaComposite su Graphics2D utilizzando setComposite. Questo controlla il livello di trasparenza.
    • Disegna l'immagine.

Per ogni iterazione della vostra animazione fade-out si cambierebbe i valori del AlphaComposite per rendere l'immagine più trasparente.

+0

Il mio componente è un componente figlio, quando ho usato paintComponent, ha dipinto l'intero genitore all'interno di JPanel, sovrascrivendo il colore (Graphics g) invece lo ha risolto. È corretto? – blank

12

Ecco un esempio utilizzando la trasparenza alfa. È possibile utilizzare this composite tool per vedere il risultato dell'utilizzo di colori, modalità e alfa diversi.

image

import java.awt.*; 
import java.awt.event.*; 
import java.awt.event.ActionListener; 
import javax.swing.*; 

public class AlphaTest extends JPanel implements ActionListener { 

    private static final Font FONT = new Font("Serif", Font.PLAIN, 32); 
    private static final String STRING = "Mothra alert!"; 
    private static final float DELTA = -0.1f; 
    private static final Timer timer = new Timer(100, null); 
    private float alpha = 1f; 

    AlphaTest() { 
     this.setPreferredSize(new Dimension(256, 96)); 
     this.setOpaque(true); 
     this.setBackground(Color.black); 
     timer.setInitialDelay(1000); 
     timer.addActionListener(this); 
     timer.start(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setFont(FONT); 
     int xx = this.getWidth(); 
     int yy = this.getHeight(); 
     int w2 = g.getFontMetrics().stringWidth(STRING)/2; 
     int h2 = g.getFontMetrics().getDescent(); 
     g2d.fillRect(0, 0, xx, yy); 
     g2d.setComposite(AlphaComposite.getInstance(
      AlphaComposite.SRC_IN, alpha)); 
     g2d.setPaint(Color.red); 
     g2d.drawString(STRING, xx/2 - w2, yy/2 + h2); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     alpha += DELTA; 
     if (alpha < 0) { 
      alpha = 1; 
      timer.restart(); 
     } 
     repaint(); 
    } 

    static public void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       JFrame f = new JFrame(); 
       f.setLayout(new GridLayout(0, 1)); 
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       f.add(new AlphaTest()); 
       f.add(new AlphaTest()); 
       f.add(new AlphaTest()); 
       f.pack(); 
       f.setVisible(true); 
      } 
     }); 
    } 
} 
+1

Per il confronto, vedere questo [esempio] (http: // stackoverflow.it/questions/2123841/javax-swing-timer-repeats-fine-but-actionlistener-doesnt-do-anything/2124507 # 2124507) che varia la saturazione del colore di sfondo. – trashgod

Problemi correlati