如何在JPanel中使3张图像淡入和淡出? [英] How to make 3 images fade in and fade out in JPanel?

查看:143
本文介绍了如何在JPanel中使3张图像淡入和淡出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题是我如何使第一张图像消失,然后第二张图像消失,然后第三张图像消失.我试图在这里和那里改变,但没有任何效果.一切都马上出来.有人可以告诉我应该更改哪一部分吗?

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.

动画是随着时间变化的幻觉.因此,您首先需要以某种方式在一段时间内更改alpha的状态.因为Swing既是单线程的又不是线程安全的,所以这为您提供了一个基本选择,即Swing Timer.

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. Because Swing is both single threaded and not thread safe, this leaves you with one basic choice, a Swing Timer.

这会定期生成更新,这些更新是事件调度线程上下文中的触发器,从而可以安全地与Swing一起使用并从内部更新UI.

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.

由于硬件(和操作系统)的差异,我避免使用固定的速率衰减(即,将固定的delta应用于alpha并重复直到达到target).这种方法可能会在不同的系统上产生不良结果.

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). This approach can produce undesirable results on different systems.

根据我的经验,基于时间的解决方案通常会产生更一致的结果.基于时间的方法表示动画将在指定的时间段内运行,在Timer的每个刻度上,我们计算量进度并将其应用于状态(我们知道我们需要从0-1逐渐消失,图片,因此很容易根据进度来计算状态)

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)

所有这些听起来都是在实践中找到的,但是我们如何实际应用它.因为解决方案并不总是那么简单,所以我将重点放在制作一个专用类来执行该操作上.

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

}

FadePane拍摄source图像,并根据您调用的方法在2秒钟的时间内淡入或淡出它.

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,只需通过setSource方法更改source图像,然后根据想要的结果将新图像淡入或淡出即可.

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.

FadePane还提供了一个观察者,在开始和完成淡入淡出操作时会得到通知...

The FadePane also provides an observer, which is notified when the fade operation is started and completed...

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

这可用于更改UI的状态(禁用/启用功能)以及在需要时切换图像

This could be used to change the state of the UI (disable/enable functionality) as well as switch the image when you want to

这个简单的示例允许用户淡入和淡出相同的图像,但是生成List图像并通过FadeListener

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

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

    }

}

这篇关于如何在JPanel中使3张图像淡入和淡出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆