在Java Swing中显示运动图像 [英] Display moving image in Java Swing

查看:169
本文介绍了在Java Swing中显示运动图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Java Swing中显示高宽度图像(比如2000x100,就像心率条一样)。我需要只显示一个宽度为500的窗口,同时它向左略微移动。我当前的代码(有点复杂,它也有不必要的动画)这样做,但我需要添加的功能是:图像的结尾应该与图像的开头连接。所以它总是重复显示一遍又一遍。

I'm trying to display a high-width image in Java Swing (say 2000x100, like a heart rate strip). I need to show only a window of 500 width while it is slightly moving towards left. My current code (a bit complicated, it also has unnecessary animations) does it, but the feature I need to add is: The end of image should be concatenated with the beginning of the image. So it always repeats showing over and over.

总之,我需要加入图像的两端!我该怎么做?

In short, I need to join the two ends of image! How can I do that?

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class SlidingAnimation {

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

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

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                JPanel j = new JPanel();
                j.add(new AnimatedBar(true));
                frame.add(j);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

class AnimatedBar extends JPanel {

    private BufferedImage img;

    private Timer timer;
    private long startTime = -1;
    private int playTime = 4000;
    private int window = 500;
    private int moveX=0;
    public static boolean keepRunning=true;

    private float progress;

    public AnimatedBar(boolean x) {
        try {
            if(x)
                img = ImageIO.read(new File("strip2.jpg"));
            else
                img=null;
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        if(x){
            timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (startTime == -1) {
                        startTime = System.currentTimeMillis();
                    } else {
                        long currentTime = System.currentTimeMillis();
                        long diff = currentTime - startTime;

                        if (diff >= playTime) {
                            diff = 0;
                            startTime = -1;
                        }
                        progress = diff / (float) playTime;
                    }

                    repaint();
                }
            });
            timer.start();
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return img == null ? new Dimension(50, 50) : new Dimension(img.getWidth()/3, img.getHeight());
    }

    protected BufferedImage generateImage() {

        BufferedImage buffer = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = buffer.createGraphics();
        g2d.setBackground(new Color(0, 0, 0, 0));
        g2d.clearRect(0, 0, buffer.getWidth(), buffer.getHeight());
        //            g2d.drawImage(img, 500, 0, this);
        g2d.drawImage(img,0,0,500,100,(moveX++),0,window+moveX,100,this);


        float startAt = progress- 0.05f;
        float endAt = progress + 0.05f;

        if (endAt <= 0.1f) {
            startAt = 0;
            endAt = Math.max(0.1f, progress);
        } else if (endAt >= 1f) {
            endAt = 1f;
            startAt = progress;
        }

        LinearGradientPaint lgp = new LinearGradientPaint(
                new Point2D.Float(0, 0),
                new Point2D.Float(img.getWidth(), 0),
                new float[]{startAt, endAt},
                new Color[]{new Color(0, 0, 0, 0), Color.RED});

        g2d.setPaint(lgp);

        g2d.setComposite(AlphaComposite.DstOut.derive(1f));
        g2d.fill(new Rectangle(0, 0, img.getWidth(), img.getHeight()));
        g2d.dispose();

        return buffer;

    }

    public void setImg(BufferedImage img) {
        this.img = img;
    }

    @Override
    protected void paintComponent(Graphics g) {
        if(keepRunning==false){
            img=null;
        }
        else{
            try {
                img = ImageIO.read(new File("strip2.jpg"));
            } catch (IOException e) {
            }
        }
            super.paintComponent(g);
            if (img != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                int y = (getHeight() - img.getHeight()) / 2;
                int x = (getWidth() - img.getWidth()/3) / 2;
                g2d.drawImage(generateImage(), x, y, this);

                g2d.dispose();
        }
    }

}


推荐答案


图像的结尾应该与图像的开头连接起来。所以它总是重复显示

The end of image should be concatenated with the beginning of the image. So it always repeats showing

查看 Marquee Panel 。您可以使用 ImageIcon JLabel 添加到 MarqueePanel

Check out the Marquee Panel. You can add a JLabel with an ImageIcon to the MarqueePanel.

MarqueePanel 提供了各种自定义滚动的方法。

The MarqueePanel provides various method to customize the scrolling.

编辑:

基本代码为:

MarqueePanel panel = new MarqueePanel();
panel.setWrap(true);
panel.setWrapAmount(0);
panel.setPreferredWidth(250);

JLabel label = new JLabel( new ImageIcon( "heartbeat.jpg" ) );
panel.add( label );

frame.add( panel );

如果您希望图像在显示时完全显示在左侧,您可以更改 startScrolling()方法并使用 scrollOffset = 0;

If you want the image to fully appear at the left when it is displayed you can change the startScrolling() method and use scrollOffset = 0;.

这篇关于在Java Swing中显示运动图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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