简体   繁体   English

如何在JPanel中使3张图像淡入淡出?

[英]How to make 3 images fade in and fade out in JPanel?

My question is how do i make first image dissappear then sec image come in the it vanish then come the third image. 我的问题是我如何使第一张图像消失,然后第二张图像消失,然后第三张图像消失。 i tried to alter here and there but nothing work. 我试图在这里和那里改变,但没有任何效果。 it all come out at once. 一切都立刻出现。 can someone tell me which part should i alter? 有人可以告诉我应该更改哪一部分吗?

  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);
 }
 }

Theory... 理论...

Okay, so based on your requirement, my first suggest is to focus on fading a single image in and out. 好的,因此根据您的要求,我的第一个建议是着重于淡入淡出单个图像。 If you can understand how to do that, then fading three images in out (one after the other) is much simpler. 如果您了解如何做到这一点,那么将三张图像淡入淡出(一个接一个)就容易得多。

Animation is the illusion of change over time. 动画是随着时间变化的幻觉。 So, you first need someway to change the state of the alpha over a period of time. 因此,您首先需要以某种方式在一段时间内更改alpha的状态。 Because Swing is both single threaded and not thread safe, this leaves you with one basic choice, a Swing Timer . 因为Swing既是单线程的又不是线程安全的,所以这为您提供了一个基本选择,即Swing Timer

This generates updates at regular intervals which are triggers within the context of the Event Dispatching Thread, making it safe to use with Swing and to update the UI from within. 这将定期生成更新,这些更新是事件调度线程上下文中的触发器,从而可以安全地与Swing一起使用并从内部更新UI。

Because of the variances in hardware (and OS's), I'd avoid a fixed rate fade (that is, where you apply a fixed delta to the alpha and repeat until your reach your target ). 由于硬件(和操作系统)的差异,我避免使用固定的速率衰减(即,将固定的delta应用于alpha并重复直到达到target )。 This approach can produce undesirable results on different systems. 这种方法可能在不同的系统上产生不良结果。

From my experience, a time based solution generally produces more consistent results. 根据我的经验,基于时间的解决方案通常会产生更一致的结果。 A time based approach states that the animation will run over a specified time period, on each tick of the Timer , we calculate the amount progression and apply that to our state (we know we need to go from 0-1 to fade an image in, so it's easy to calculate the state based on the progression) 基于时间的方法表示动画将在指定的时间段内运行,在Timer每个刻度上,我们计算量进度并将其应用于状态(我们知道我们需要从0-1开始淡入图像, ,因此很容易根据进度来计算状态)

Base implementation... 基本实施...

That all sounds find in practice, but how do we actually apply it. 所有这些听起来都可以在实践中找到,但是我们如何实际应用它。 Because the solution isn't always simple, I'd focus on making a dedicated class to perform the operation. 因为解决方案并不总是那么简单,所以我将重点放在制作专用类来执行操作上。

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();
    }

}

The FadePane takes a source image and, depending on which method you call, will fade it in or out over a period of 2 seconds. FadePane会获取source图像,并且会根据您调用的方法在2秒钟的时间内淡入或淡出它。

You can re-use the FadePane by simply changing the source image via the setSource method and fading the new image in or out, depending on the desired result you're after. 您可以简单地通过setSource方法更改source图像,然后根据想要的结果使新图像淡入或淡出,从而重新使用FadePane

The FadePane also provides an observer, which is notified when the fade operation is started and completed... FadePane还提供了一个观察者,当淡入淡出操作开始和完成时会收到通知。

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

This could be used to change the state of the UI (disable/enable functionality) as well as switch the image when you want to 这可用于更改UI的状态(禁用/启用功能)以及在需要时切换图像

Runnable Example... 可运行的示例...

This example simple allows a user to fade the same image in and out, but it wouldn't be hard to generate a List of images which which are changed through the FadeListener 这个简单的示例允许用户淡入淡出相同的图像,但是生成通过FadeListener更改的图像List并不难

褪色

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();
        }

    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM