public void save(File file) {
        try {
            if (file.exists()) {
                file.delete();
                file.createNewFile();
            }
            Map<String, BufferedImage> images = new HashMap<>();
            ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(file));
            for (Map.Entry<Integer, AnimationFrame> frame : frames.entrySet()) {
                ZipEntry skeletonPropertiesEntry = new ZipEntry("/frames/" + frame.getKey() + "/skeleton.properties");
                zipOutputStream.putNextEntry(skeletonPropertiesEntry);
                Properties skeletonProperties = frame.getValue().getSkeleton().asProperties();
                skeletonProperties.store(zipOutputStream, "");
                zipOutputStream.closeEntry();
                images.putAll(frame.getValue().getSkeleton().getImages());
                ZipEntry lightSourcesPropertiesEntry = new ZipEntry("/frames/" + frame.getKey() + "/lightsources.properties");
                zipOutputStream.putNextEntry(lightSourcesPropertiesEntry);
                Properties lightSourceProperties = frame.getValue().lightSourcesAsProperties();
                lightSourceProperties.store(zipOutputStream, "");
                zipOutputStream.closeEntry();
            }
            for (Map.Entry<String, BufferedImage> image : images.entrySet()) {
                if (!image.getKey().equals("null")) {
                    ZipEntry imageEntry = new ZipEntry("/images/" + image.getKey());
                    zipOutputStream.putNextEntry(imageEntry);
                    ImageIO.write(image.getValue(), "png", zipOutputStream);
                    zipOutputStream.closeEntry();
                }
            }
            ZipEntry animationPropertiesEntry = new ZipEntry("/animation.properties");
            zipOutputStream.putNextEntry(animationPropertiesEntry);
            Properties animationProperties = new Properties();
            animationProperties.setProperty("frames", "" + getSettingsPanel().getFrames());
            animationProperties.setProperty("width", "" + getCanvasWidth());
            animationProperties.setProperty("height", "" + getCanvasHeight());
            animationProperties.store(zipOutputStream, "");
            zipOutputStream.closeEntry();
            zipOutputStream.close();
        } catch (IOException exception) {
            exception.printStackTrace();
        }
    }