在Java Swing中显示运动图像 [英] Display moving image in 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屋!