2017-12-02 216 views
0

我的問題是我如何使第一個圖像消失,然後第二個圖像進入它消失,然後來到第三個圖像。我試圖在這裏和那裏改變,但沒有任何工作。這一切都馬上出來。有人能告訴我哪一部分應該改變嗎?如何讓3個圖像在JPanel中淡入和淡出?

import java.awt.AlphaComposite; 
    import java.awt.Graphics; 
    import java.awt.Graphics2D; 
    import java.awt.Image; 
    import java.awt.event.ActionEvent; 
    import java.awt.event.ActionListener; 
    import javax.swing.ImageIcon; 
    import javax.swing.JFrame; 
    import javax.swing.JPanel; 
    import javax.swing.Timer; 

    public class FadeOutImage2 extends JPanel implements ActionListener{ 

    Image myImage = new ImageIcon("C:\\Users\\NUR\\Pictures\\FLOWER1.jpg").getImage(); 
    Image myImage2 = new ImageIcon("C:\\Users\\NUR\\Pictures\\FLOWER2.jpg").getImage(); 
    Image myImage3 = new ImageIcon("C:\\Users\\NUR\\Pictures\\FLOWER3.jpg").getImage(); 

    Timer timer = new Timer (50, this); //setting time to fade 
    private float alpha = 1f; //alpha value on channel 

    public FadeOutImage2(){ 
    timer.start(); 
    } 

    public void paint(Graphics g){ 
    super.paint(g); 

    Graphics2D g2d = (Graphics2D)g; 
    Graphics2D g2d2 = (Graphics2D)g; 
    Graphics2D g2d3 = (Graphics2D)g; 


g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,alpha)); 
g2d2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,alpha)); 
g2d3.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,alpha)); 

g2d.drawImage(myImage, 10,10, null); //coordinate 
g2d2.drawImage(myImage2, 10,10, null); 
g2d3.drawImage(myImage3, 10,10, null); 
    } 

    public void actionPerformed(ActionEvent e){ 
     alpha += -0.01f; 
     if(alpha<=0){ 
     alpha=0; 
     timer.stop();} 

     repaint(); 
    } 

public static void main(String[] args){ 
    JFrame frame = new JFrame("Fade Out"); 
    frame.add(new FadeOutImage2()); 

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setSize(1500,1500); 
    frame.setVisible(true); 
} 
} 
+0

改變你的意思是類似[this](https://stackoverflow.com/questions/20346661/java-fade-in-and-out-of-images/20347600#20347600)和[this](https://stackoverflow.com /問題/ 34119221/Java的漸入和出兩個jpanels-在最相同的時間/ 34123681#34123681) – MadProgrammer

回答

1

理論...

好了,根據您的需要,我的第一個建議是把重點放在淡入和淡出單個圖像。如果你能夠理解如何做到這一點,那麼將三張圖像逐個(一個接一個地)褪色就簡單多了。

動畫是隨時間變化的錯覺。所以,你首先需要在一段時間內改變alpha的狀態。因爲Swing既是單線程的,也不是線程安全的,所以這給你一個基本的選擇,一個Swing Timer

這會在Event Dispatching Thread的上下文中定期生成更新,這些觸發器可以安全地用於Swing並從內部更新UI。

由於在硬件上的差異(和操作系統的),我會避免固定利率褪色(即,當你申請一個固定deltaalpha和重複,直到你達到你的target)。這種方法會在不同的系統上產生不希望的結果。

根據我的經驗,基於時間的解決方案通常會產生更一致的結果。基於時間的方法指出,動畫將在指定的時間段內運行,在Timer的每個勾號上,我們計算數量進展並將其應用於我們的狀態(我們知道我們需要從0-1開始淡入圖像,所以很容易計算基於進程)

器的基本實現

這聽起來都在實踐中找到狀態......,但我們究竟要如何應用它。因爲解決方案並不總是很簡單,所以我會專注於製作專門的課程來執行操作。

public class FadePane extends JPanel { 

    private BufferedImage source; 
    private Timer timer; 

    private float alpha = 1.0f; 

    private int duration = 2000; // 2 seconds 
    private Long startTime; 

    private boolean fadeOut = false; 

    private FadeListener fadeListener; 

    public FadePane(BufferedImage source) { 
     this.source = source; 
     timer = new Timer(5, new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       if (startTime == null) { 
        startTime = System.currentTimeMillis(); 
        fadeStarted(); 
       } 
       long diff = System.currentTimeMillis() - startTime; 
       alpha = (float)diff/(float)duration; 
       if (alpha > 1.0) { 
        timer.stop(); 
        alpha = 1.0f; 
        fadeCompleted(); 
       } 
       if (fadeOut) { 
        alpha = 1.0f - alpha; 
       } 
       repaint(); 
      } 
     }); 
    } 

    public void setFadeListener(FadeListener listener) { 
     fadeListener = listener; 
    } 

    public boolean isFadeOut() { 
     return fadeOut; 
    } 

    protected void fadeStarted() { 
     if (fadeListener != null) { 
      fadeListener.fadeStarted(this); 
     } 
    } 

    protected void fadeCompleted() { 
     if (fadeListener != null) { 
      fadeListener.fadeCompleted(this); 
     } 
    } 

    public void setSource(BufferedImage img) { 
     source = img; 
    } 

    public void reset() { 
     timer.stop(); 
     alpha = 0; 
     startTime = null; 
    } 

    public void fadeIn() { 
     reset(); 
     fadeOut = false; 
     timer.start(); 
    } 

    public void fadeOut() { 
     reset(); 
     fadeOut = true; 
     timer.start(); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return source == null ? new Dimension(200, 200) : new Dimension(source.getWidth(), source.getHeight()); 
    } 

    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g.create(); 
     g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); 
     int x = (getWidth() - source.getWidth())/2; 
     int y = (getHeight() - source.getHeight())/2; 
     g2d.drawImage(source, x, y, this); 
     g2d.dispose(); 
    } 

} 

FadePane的需要source圖像,並且根據調用該方法時,會褪色它或縮小歷時2秒。

您可以通過簡單地改變通過setSource方法source圖像和褪色或縮小的新形象,這取決於你以後想要的結果重複使用FadePane

FadePane的還提供了一個觀察者,當淡變操作開始並完成該通知...

public interface FadeListener { 
    public void fadeStarted(FadePane pane); 
    public void fadeCompleted(FadePane pane); 
} 

這可以被用於改變用戶界面的狀態(禁用/啓用的功能),其以及當您想要切換圖像時

Runnable示例...

這個例子簡單允許用戶褪色相同的圖像和縮小,但它不會是難以產生圖像的List其中它們通過FadeListener

Fade

import java.awt.AlphaComposite; 
import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.imageio.ImageIO; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Test { 

    public static void main(String[] args) { 
     new Test(); 
    } 

    public Test() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        try { 
         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
         ex.printStackTrace(); 
        } 

        BufferedImage source = ImageIO.read(...); 
        FadePane fadePane = new FadePane(source); 
        JButton btn = new JButton("Fade"); 
        btn.addActionListener(new ActionListener() { 
         private boolean fadeOut = true; 
         @Override 
         public void actionPerformed(ActionEvent e) { 
          if (fadeOut) { 
           fadePane.fadeOut(); 
          } else { 
           fadePane.fadeIn(); 
          } 
          fadeOut = !fadeOut; 
         } 
        }); 

        fadePane.setFadeListener(new FadeListener() { 
         @Override 
         public void fadeStarted(FadePane pane) { 
          btn.setEnabled(false); 
         } 

         @Override 
         public void fadeCompleted(FadePane pane) { 
          // Set next image and start the 
          // fade process again 
          btn.setEnabled(true); 
         } 
        }); 

        JFrame frame = new JFrame("Testing"); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        frame.add(fadePane); 
        frame.add(btn, BorderLayout.SOUTH); 
        frame.pack(); 
        frame.setLocationRelativeTo(null); 
        frame.setVisible(true); 
       } catch (IOException ex) { 
        ex.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public interface FadeListener { 
     public void fadeStarted(FadePane pane); 
     public void fadeCompleted(FadePane pane); 
    } 

    public class FadePane extends JPanel { 

     private BufferedImage source; 
     private Timer timer; 

     private float alpha = 1.0f; 

     private int duration = 2000; // 2 seconds 
     private Long startTime; 

     private boolean fadeOut = false; 

     private FadeListener fadeListener; 

     public FadePane(BufferedImage source) { 
      this.source = source; 
      timer = new Timer(5, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        if (startTime == null) { 
         startTime = System.currentTimeMillis(); 
         fadeStarted(); 
        } 
        long diff = System.currentTimeMillis() - startTime; 
        alpha = (float)diff/(float)duration; 
        if (alpha > 1.0) { 
         timer.stop(); 
         alpha = 1.0f; 
         fadeCompleted(); 
        } 
        if (fadeOut) { 
         alpha = 1.0f - alpha; 
        } 
        repaint(); 
       } 
      }); 
     } 

     public void setFadeListener(FadeListener listener) { 
      fadeListener = listener; 
     } 

     protected void fadeStarted() { 
      if (fadeListener != null) { 
       fadeListener.fadeStarted(this); 
      } 
     } 

     protected void fadeCompleted() { 
      if (fadeListener != null) { 
       fadeListener.fadeCompleted(this); 
      } 
     } 

     public void setSource(BufferedImage img) { 
      source = img; 
     } 

     public void reset() { 
      timer.stop(); 
      alpha = 0; 
      startTime = null; 
     } 

     public boolean isFadeOut() { 
      return fadeOut; 
     } 

     public void fadeIn() { 
      reset(); 
      fadeOut = false; 
      timer.start(); 
     } 

     public void fadeOut() { 
      reset(); 
      fadeOut = true; 
      timer.start(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return source == null ? new Dimension(200, 200) : new Dimension(source.getWidth(), source.getHeight()); 
     } 

     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); 
      int x = (getWidth() - source.getWidth())/2; 
      int y = (getHeight() - source.getHeight())/2; 
      g2d.drawImage(source, x, y, this); 
      g2d.dispose(); 
     } 

    } 

}