2017-12-02 151 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(); 
     } 

    } 

}