/*******************************************************************************
* Copyright (c) 2016 Alex Shapiro - github.com/shpralex
* This program and the accompanying materials
* are made available under the terms of the The MIT License (MIT)
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*******************************************************************************/
package com.sproutlife.action;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.imageio.ImageIO;
import javax.imageio.stream.FileImageOutputStream;
import javax.imageio.stream.ImageOutputStream;
import javax.swing.AbstractAction;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import com.sproutlife.io.GifSequenceWriter;
import com.sproutlife.panel.PanelController;
@SuppressWarnings("serial")
public class ExportGifAction extends AbstractAction {
protected PanelController controller;
protected String defaultFileName = "SproutLife";
private JFileChooser chooser = null;
public ExportGifAction(PanelController controller, String name) {
super(name);
this.controller = controller;
}
public ExportGifAction(PanelController controller) {
this(controller, "Save Gif");
}
public void setDefaultFileName(String defaultFileName) {
this.defaultFileName=defaultFileName;
if (chooser!=null) {
chooser.setSelectedFile(new File(defaultFileName));
}
}
public void initChooser() {
if (chooser!=null) return;
chooser = new JFileChooser();
chooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
chooser.setAcceptAllFileFilterUsed(false);
String date = new SimpleDateFormat(" yyyy-MM-dd").format(new Date());
defaultFileName+=date+".gif";
chooser.setSelectedFile(new File(defaultFileName));
chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
public boolean accept(File f) {
return f.getName().toLowerCase().endsWith(".gif")
|| f.isDirectory();
}
public String getDescription() {
return "gif files (*.gif)";
}
});
}
public void actionPerformed(ActionEvent e) {
initChooser();
controller.getScrollController().updateScrollBars();
controller.setPlayGame(false);
int returnVal = chooser.showSaveDialog(controller.getGameFrame());
File saveFile;
if (returnVal == JFileChooser.APPROVE_OPTION) {
saveFile = chooser.getSelectedFile();
String fileName = saveFile.getName();
if (fileName.indexOf(".") < 0) {
try {
String filePath = saveFile.getPath();
saveFile = new File(filePath + ".gif");
} catch (Exception ex) {
ex.printStackTrace();
}
}
final File finalSaveFile = saveFile;
new Thread() {
@Override
public void run() {
try {
saveImage(finalSaveFile);
} catch (Exception ex) {
JOptionPane.showMessageDialog(controller.getGameFrame(), "Image is too large, or nothing to draw");
}
}
}.start();
}
}
public void saveImage(File saveFile) throws Exception {
int width = (int) controller.getBoardRenderer().getRendererBounds().getWidth();
width = Math.min(width,controller.getScrollPanel().getViewportSize().width);
int height = width*9/16;
BufferedImage firstImage = controller.getImageManager().getCroppedExportImage(width, height);
// create a new BufferedOutputStream with the last argument
ImageOutputStream output =
new FileImageOutputStream(saveFile);
// create a gif sequence with the type of the first image, 1 second
// between frames, which loops continuously
GifSequenceWriter writer =
new GifSequenceWriter(output, firstImage.getType(), 1, true);
// write out the first image to our sequence...
writer.writeToSequence(firstImage);
for(int i=0; i<200; i++) {
int skipFrames = 4;
if (controller.getBoardRenderer().getBlockSize()==4) {
skipFrames = 2;
}
if (controller.getBoardRenderer().getBlockSize()>4) {
skipFrames = 1;
}
for(int j=0; j<skipFrames; j++) {
controller.getInteractionLock().writeLock().lock();
controller.getGameModel().performGameStep();
controller.getInteractionLock().writeLock().unlock();
controller.getImageManager().repaintNewImage();
}
BufferedImage nextImage = controller.getImageManager().getCroppedExportImage(width, height);
writer.writeToSequence(nextImage);
}
writer.close();
output.close();
}
}