按组Java Swing设置图像列表动画
当前,我的代码将从列表中的图像从初始大小设置为最终大小,并继续设置下一个图像,直到完成所有图像的动画设置,并且所有图像都具有最终大小按组Java Swing设置图像列表动画,java,swing,animation,Java,Swing,Animation,当前,我的代码将从列表中的图像从初始大小设置为最终大小,并继续设置下一个图像,直到完成所有图像的动画设置,并且所有图像都具有最终大小 package ui; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing
package ui;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.Timer;
import utils.SudokuGen;
// TODO: Auto-generated Javadoc
/**
* The Class ButtonPanel.
*/
public class ButtonPanel extends JPanel implements ActionListener{
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
/** The buttons. */
private JButton[] buttons;
private int[] imgsize;
private int index,count;
private Timer timer;
private ImageButton images;
private static final int COUNT = 10;
private static final int INITSIZE = 32;
private static final int COLUMNS = 1;
private static final int ROWS = 9;
/**
* Instantiates a new button panel.
*
* @param puzzle The Sudoku matrix object
* @param images The images object
* @param sPanel The Sudoku JPanel
*/
public ButtonPanel(SudokuGen puzzle, ImageButton images, SudokuPanel sPanel){
//Create an array of JButton with 9 elements
this.buttons = new JButton[puzzle.getMyboard().getNewnumbers().size()];
this.images = images;
this.imgsize = new int[COUNT];
for (int i=0;i<COUNT;i++){
imgsize[i] = INITSIZE;
}
//Sets the layout to a 9*1 GridLayout with padding 5
this.setLayout(new GridLayout(ROWS,COLUMNS,5,5));
//Load an image, create the MouseListener and add it at index i
for (int i=1;i<this.images.getImagelist().size();i++){
ImageIcon image = new ImageIcon(this.images.getImagelist()
.get(i).getImage().getScaledInstance(32, 32, Image.SCALE_SMOOTH));
buttons[i] = createMouseListener(image, i, puzzle, sPanel);
buttons[i].setPreferredSize(new Dimension(100, 100));
this.add(buttons[i]);
}
index = 1; //first button
count = 0; //times to resize the button
timer = new Timer(5,this);
timer.start();
}
public void set(int X){
this.imgsize[index] = X;
}
/**
* Creates the mouse listener.
*
* @param image The image at index i
* @param i The index for the button i
* @param puzzle The Sudoku matrix object
* @param sPanel The Sudoku JPanel
* @return the JButton to add at index i
*/
private JButton createMouseListener(ImageIcon image, int i, SudokuGen puzzle, SudokuPanel sPanel){
JButton button = new JButton();
button.setIcon(image);
button.setActionCommand(Integer.toString(puzzle.getMyboard().getNewnumbers().get(i)));
button.addActionListener(sPanel.new ButtonActionListener());
return button;
}
@Override
public void actionPerformed(ActionEvent e) {
count++;
set(this.imgsize[index]+1); //increase the size of the image
if (this.imgsize[index] < 64){
ImageIcon image = new ImageIcon(this.images.getImagelist()
.get(index).getImage().getScaledInstance(this.imgsize[index], this.imgsize[index], Image.SCALE_SMOOTH));
buttons[index].setIcon(image);
if (count > 24){ //reached final size
count = 0; //start counting again
index++; //move to the next image
}
};
if (index == 10) timer.stop();
repaint();
}
}
packageui;
导入java.awt.Dimension;
导入java.awt.GridLayout;
导入java.awt.Image;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入javax.swing.ImageIcon;
导入javax.swing.JButton;
导入javax.swing.JPanel;
导入javax.swing.Timer;
导入utils.SudokuGen;
//TODO:自动生成的Javadoc
/**
*类按钮面板。
*/
公共类ButtonPanel扩展JPanel实现ActionListener{
/**常量serialVersionId*/
私有静态最终长serialVersionUID=1L;
/**按钮*/
私有JButton[]按钮;
私有int[]imgsize;
私有int索引,计数;
私人定时器;
私有图像按钮图像;
私有静态最终整数计数=10;
私有静态final int INITSIZE=32;
私有静态final int COLUMNS=1;
私有静态最终整数行=9;
/**
*实例化一个新的按钮面板。
*
*@param拼图数独矩阵对象
*@param images图像对象
*@param sPanel数独游戏
*/
公共按钮面板(SudokuGen拼图、ImageButton图像、SudokuGen拼板){
//创建一个包含9个元素的JButton数组
this.buttons=newjbutton[puzzle.getMyboard().getNewnumbers().size()];
这个。图像=图像;
this.imgsize=新整数[计数];
对于(int i=0;i 24){
计数=0;
索引++;
}
如果(计数>12&&索引<9)
{
this.imgsize[index+1]++;
image=newImageIcon(this.images.getImagelist()
.get(index+1).getImage().getScaleInstance(this.imgsize[index+1],this.imgsize[index+1],Image.SCALE_-SMOOTH));
按钮[索引+1]。设置图标(图像);
}
如果(索引==10)timer.stop();
重新油漆();
}
这是一个过于简化的想法
基本上,它建立了一个标准化的时间线(0-1),事件可以沿着时间线发生,从指定的点开始和结束。在这些“时间段”中,可能会发生一些“动作”
在您的案例中,这些操作是图像缩放操作,其缩放比例是给定事件已运行时间的比例,是整个时间线的比例
这听起来非常令人困惑,但其好处是,您可以更改时间线的持续时间,其余代码将自动缩放
例如,你可以采取
timeline = new Timeline(events, 10000);
它会生成一个时间线,运行超过10秒,并将其更改为
timeline = new Timeline(events, 5000);
这将生成一个运行时间超过5秒的时间线,并且您不必更改一行代码即可使其正常工作
我还花了一些时间研究如何从一系列图像中自动生成时间线事件,这样您就可以提供n
数量的图像,它将生成所需的事件,以便它们相应地相互重叠
现在,你可能认为这太复杂了,但关键是,这都是可变的,图像缩放的持续时间,图像的数量,都是可变的,你不需要做很多事情来添加/删除图像或更改持续时间
Cavert-我在本例中使用了GetScaleInstance
,它既不快速,也不能生成高质量的图像
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
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.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
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 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();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
private Timeline timeline;
private Map<Object, Image> mapImages = new HashMap<>(5);
private List<Object> imageOrder = new ArrayList<>(5);
public TestPane() throws IOException {
BufferedImage[] images = new BufferedImage[]{
ImageIO.read(new File("...")),
ImageIO.read(new File("...")),
ImageIO.read(new File("...")),
ImageIO.read(new File("..."))
};
List<TimelineEvent> events = generateEvents(images, new ImageScaledObserver() {
@Override
public void imageScaled(Object id, Image image) {
if (!imageOrder.contains(id)) {
imageOrder.add(id);
}
mapImages.put(id, image);
repaint();
}
});
timeline = new Timeline(events, 10000);
Timer timer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (timeline.update()) {
((Timer) e.getSource()).stop();
}
}
});
timer.setInitialDelay(5000);
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (Object id : imageOrder) {
Image image = mapImages.get(id);
int x = (getWidth() - image.getWidth(this)) / 2;
int y = (getHeight() - image.getHeight(this)) / 2;
g2d.drawImage(image, x, y, this);
}
g2d.dispose();
}
}
protected List<TimelineEvent> generateEvents(BufferedImage[] images, ImageScaledObserver observer) {
double length = 1.0 / (double) (images.length);
double overlap = length * 0.5;
List<TimelineEvent> events = new ArrayList<>(images.length);
double startAt = 0.0;
for (BufferedImage image : images) {
double endAt = Math.min(startAt + length + (overlap / 2.0), 1.0);
events.add(new ScaleImageTimelineEvent(image, observer, startAt, endAt));
startAt = Math.min(endAt - (overlap / 2.0), 1.0);
}
return events;
}
public interface TimelineEvent {
public double[] range();
public boolean isWithin(double timelineProgression);
public void performAction(double timelineProgression);
}
public abstract class AbstractTimelineEvent implements TimelineEvent {
private double from, to;
public AbstractTimelineEvent(double from, double to) {
this.from = from;
this.to = to;
}
@Override
public double[] range() {
return new double[]{from, to};
}
@Override
public boolean isWithin(double timelineProgression) {
boolean within = timelineProgression >= from && timelineProgression <= to;
return within;
}
protected double localisedProgression(double timelineProgression) {
double max = from - to;
double value = timelineProgression - to;
double weight = value / max;
return 1d - weight;
}
}
public interface ImageScaledObserver {
public void imageScaled(Object id, Image img);
}
public class ScaleImageTimelineEvent extends AbstractTimelineEvent {
private BufferedImage original;
private ImageScaledObserver observer;
private UUID id;
public ScaleImageTimelineEvent(BufferedImage image, ImageScaledObserver observer, double from, double to) {
super(from, to);
this.original = image;
this.observer = observer;
this.id = UUID.randomUUID();
}
@Override
public void performAction(double timelineProgression) {
double progress = localisedProgression(timelineProgression);
Image image = null;
if (progress < 1.0) {
int width = (int) (original.getWidth() * progress);
if (width > 0) {
image = original.getScaledInstance((int) (original.getWidth() * progress), -1, Image.SCALE_FAST);
}
} else {
image = original;
}
if (image != null) {
observer.imageScaled(id, image);
}
}
}
public static class Timeline {
private List<TimelineEvent> events;
private Long startTime;
private long duration;
public Timeline(List<TimelineEvent> events, long duration) {
this.events = events;
this.duration = duration;
}
public List<TimelineEvent> getEvents() {
return events;
}
public Long getStartTime() {
return startTime;
}
public long getDuration() {
return duration;
}
public void start() {
if (startTime == null) {
startTime = System.nanoTime();
}
}
public void stop() {
startTime = null;
}
public boolean update() {
if (startTime == null) {
start();
}
boolean completed = false;
long currentTime = System.nanoTime();
long diff = currentTime - getStartTime();
long nanoDuration = TimeUnit.NANOSECONDS.convert(getDuration(), TimeUnit.MILLISECONDS);
double progress = diff / (double) nanoDuration;
if (progress > 1.0d) {
progress = 1.0d;
completed = true;
stop();
}
for (TimelineEvent evt : getEvents()) {
if (evt.isWithin(progress)) {
evt.performAction(progress);
}
}
return completed;
}
}
}
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Image;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.image.buffereImage;
导入java.io.File;
导入java.io.IOException;
导入java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入java.util.UUID;
导入java.util.concurrent.TimeUnit;
导入javax.imageio.imageio;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.Timer;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公开课考试{
公共静态void main(字符串[]args){
新测试();
}
公开考试(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
例如printStackTrace();
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(newtestpane());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}捕获(IOEX异常){
例如printStackTrace();
}
}
});
}
公共类TestPane扩展了JPanel{
私人时间表;
私有映射mapImages=newhashmap(5);
私有列表imageOrder=新的ArrayList(5);
公共TestPane()引发IOException{
BuffereImage[]图像=新的BuffereImage[]{
ImageIO.read(新文件(“…”),
ImageIO.read(新文件(“…”),
ImageIO.read(新文件(“…”),
ImageIO.read(新文件(“…”)
};
List events=generateEvents(图像,新图像缩放的观察服务器(){
@凌驾
public void imageScaled(对象id、图像){
如果(!imageOrder.contains(id)){
imageOrder.add(id);
}
mapI
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
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.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
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 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();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
private Timeline timeline;
private Map<Object, Image> mapImages = new HashMap<>(5);
private List<Object> imageOrder = new ArrayList<>(5);
public TestPane() throws IOException {
BufferedImage[] images = new BufferedImage[]{
ImageIO.read(new File("...")),
ImageIO.read(new File("...")),
ImageIO.read(new File("...")),
ImageIO.read(new File("..."))
};
List<TimelineEvent> events = generateEvents(images, new ImageScaledObserver() {
@Override
public void imageScaled(Object id, Image image) {
if (!imageOrder.contains(id)) {
imageOrder.add(id);
}
mapImages.put(id, image);
repaint();
}
});
timeline = new Timeline(events, 10000);
Timer timer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (timeline.update()) {
((Timer) e.getSource()).stop();
}
}
});
timer.setInitialDelay(5000);
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (Object id : imageOrder) {
Image image = mapImages.get(id);
int x = (getWidth() - image.getWidth(this)) / 2;
int y = (getHeight() - image.getHeight(this)) / 2;
g2d.drawImage(image, x, y, this);
}
g2d.dispose();
}
}
protected List<TimelineEvent> generateEvents(BufferedImage[] images, ImageScaledObserver observer) {
double length = 1.0 / (double) (images.length);
double overlap = length * 0.5;
List<TimelineEvent> events = new ArrayList<>(images.length);
double startAt = 0.0;
for (BufferedImage image : images) {
double endAt = Math.min(startAt + length + (overlap / 2.0), 1.0);
events.add(new ScaleImageTimelineEvent(image, observer, startAt, endAt));
startAt = Math.min(endAt - (overlap / 2.0), 1.0);
}
return events;
}
public interface TimelineEvent {
public double[] range();
public boolean isWithin(double timelineProgression);
public void performAction(double timelineProgression);
}
public abstract class AbstractTimelineEvent implements TimelineEvent {
private double from, to;
public AbstractTimelineEvent(double from, double to) {
this.from = from;
this.to = to;
}
@Override
public double[] range() {
return new double[]{from, to};
}
@Override
public boolean isWithin(double timelineProgression) {
boolean within = timelineProgression >= from && timelineProgression <= to;
return within;
}
protected double localisedProgression(double timelineProgression) {
double max = from - to;
double value = timelineProgression - to;
double weight = value / max;
return 1d - weight;
}
}
public interface ImageScaledObserver {
public void imageScaled(Object id, Image img);
}
public class ScaleImageTimelineEvent extends AbstractTimelineEvent {
private BufferedImage original;
private ImageScaledObserver observer;
private UUID id;
public ScaleImageTimelineEvent(BufferedImage image, ImageScaledObserver observer, double from, double to) {
super(from, to);
this.original = image;
this.observer = observer;
this.id = UUID.randomUUID();
}
@Override
public void performAction(double timelineProgression) {
double progress = localisedProgression(timelineProgression);
Image image = null;
if (progress < 1.0) {
int width = (int) (original.getWidth() * progress);
if (width > 0) {
image = original.getScaledInstance((int) (original.getWidth() * progress), -1, Image.SCALE_FAST);
}
} else {
image = original;
}
if (image != null) {
observer.imageScaled(id, image);
}
}
}
public static class Timeline {
private List<TimelineEvent> events;
private Long startTime;
private long duration;
public Timeline(List<TimelineEvent> events, long duration) {
this.events = events;
this.duration = duration;
}
public List<TimelineEvent> getEvents() {
return events;
}
public Long getStartTime() {
return startTime;
}
public long getDuration() {
return duration;
}
public void start() {
if (startTime == null) {
startTime = System.nanoTime();
}
}
public void stop() {
startTime = null;
}
public boolean update() {
if (startTime == null) {
start();
}
boolean completed = false;
long currentTime = System.nanoTime();
long diff = currentTime - getStartTime();
long nanoDuration = TimeUnit.NANOSECONDS.convert(getDuration(), TimeUnit.MILLISECONDS);
double progress = diff / (double) nanoDuration;
if (progress > 1.0d) {
progress = 1.0d;
completed = true;
stop();
}
for (TimelineEvent evt : getEvents()) {
if (evt.isWithin(progress)) {
evt.performAction(progress);
}
}
return completed;
}
}
}