/* * To change this template, choose Tools | Templates * and open the template in the editor. */ /* * ExportWorldDialog.java * * Created on Mar 29, 2011, 5:09:50 PM */ package org.pepsoft.worldpainter; import org.pepsoft.minecraft.ChunkFactory; import org.pepsoft.util.DesktopUtils; import org.pepsoft.util.FileUtils; import org.pepsoft.util.ProgressReceiver; import org.pepsoft.util.ProgressReceiver.OperationCancelled; import org.pepsoft.util.TaskbarProgressReceiver; import org.pepsoft.util.swing.ProgressTask; import org.pepsoft.worldpainter.exporting.WorldExporter; import javax.swing.*; import java.awt.*; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.io.File; import java.io.IOException; import java.text.NumberFormat; import java.util.Map; import static org.pepsoft.minecraft.Constants.*; /** * * @author pepijn */ public class ExportProgressDialog extends MultiProgressDialog<Map<Integer, ChunkFactory.Stats>> implements WindowListener { /** Creates new form ExportWorldDialog */ public ExportProgressDialog(Window parent, World2 world, File baseDir, String name) { super(parent, "Exporting"); if ((world.getVersion() != SUPPORTED_VERSION_1) && (world.getVersion() != SUPPORTED_VERSION_2)) { throw new IllegalArgumentException("Not a supported version: 0x" + Integer.toHexString(world.getVersion())); } this.world = world; this.baseDir = baseDir; this.name = name; addWindowListener(this); JButton minimiseButton = new JButton("Minimize"); minimiseButton.addActionListener(e -> App.getInstance().setState(Frame.ICONIFIED)); addButton(minimiseButton); } // WindowListener @Override public void windowClosed(WindowEvent e) { // Make sure to clean up any progress that is still showing DesktopUtils.setProgressDone(App.getInstance()); } @Override public void windowClosing(WindowEvent e) {} @Override public void windowOpened(WindowEvent e) {} @Override public void windowIconified(WindowEvent e) {} @Override public void windowDeiconified(WindowEvent e) {} @Override public void windowActivated(WindowEvent e) {} @Override public void windowDeactivated(WindowEvent e) {} // MultiProgressDialog @Override protected String getVerb() { return "Export"; } @Override protected String getResultsReport(Map<Integer, ChunkFactory.Stats> result, long duration) { boolean nonStandardHeight = (world.getVersion() == SUPPORTED_VERSION_1) ? (world.getMaxHeight() != DEFAULT_MAX_HEIGHT_1) : (world.getMaxHeight() != DEFAULT_MAX_HEIGHT_2); StringBuilder sb = new StringBuilder(); sb.append("<html>World exported as ").append(new File(baseDir, FileUtils.sanitiseName(name))); int hours = (int) (duration / 3600); duration = duration - hours * 3600; int minutes = (int) (duration / 60); int seconds = (int) (duration - minutes * 60); sb.append("<br>Export took ").append(hours).append(":").append((minutes < 10) ? "0" : "").append(minutes).append(":").append((seconds < 10) ? "0" : "").append(seconds); if (nonStandardHeight) { sb.append("<br><br><b>Please note:</b> this level has a non-standard height! You need to have<br>an appropriate height mod installed to play it!"); } if (result.size() == 1) { ChunkFactory.Stats stats = result.get(result.keySet().iterator().next()); sb.append("<br><br>Statistics:<br>"); dumpStats(sb, stats); } else { for (Map.Entry<Integer, ChunkFactory.Stats> entry: result.entrySet()) { int dim = entry.getKey(); ChunkFactory.Stats stats = entry.getValue(); switch (dim) { case Constants.DIM_NORMAL: sb.append("<br><br>Statistics for surface:<br>"); break; case Constants.DIM_NETHER: sb.append("<br><br>Statistics for Nether:<br>"); break; case Constants.DIM_END: sb.append("<br><br>Statistics for End:<br>"); break; default: sb.append("<br><br>Statistics for dimension " + dim + ":<br>"); break; } dumpStats(sb, stats); } } if (backupDir.isDirectory()) { sb.append("<br><br>Backup of existing map created in:<br>").append(backupDir); } sb.append("</html>"); return sb.toString(); } @Override protected String getCancellationMessage() { return "Export cancelled by user.\n\nThe partially exported map is now probably corrupted!\nYou should delete it, or export the map again." + (backupDir.isDirectory() ? ("\n\nBackup of existing map created in:\n" + backupDir) : ""); } @Override protected ProgressTask<Map<Integer, ChunkFactory.Stats>> getTask() { Configuration config = Configuration.getInstance(); if (config != null) { config.setExportDirectory(baseDir); } return new ProgressTask<Map<Integer, ChunkFactory.Stats>>() { @Override public String getName() { return "Exporting world " + name; } @Override public Map<Integer, ChunkFactory.Stats> execute(ProgressReceiver progressReceiver) throws OperationCancelled { progressReceiver = new TaskbarProgressReceiver(App.getInstance(), progressReceiver); progressReceiver.setMessage("Exporting world " + name); WorldExporter exporter = new WorldExporter(world); try { backupDir = exporter.selectBackupDir(new File(baseDir, FileUtils.sanitiseName(name))); return exporter.export(baseDir, name, backupDir, progressReceiver); } catch (IOException e) { throw new RuntimeException("I/O error while exporting world", e); } } }; } private void dumpStats(final StringBuilder sb, final ChunkFactory.Stats stats) { final NumberFormat formatter = NumberFormat.getIntegerInstance(); final long duration = stats.time / 1000; if (stats.landArea > 0) { sb.append("Land area: " + formatter.format(stats.landArea) + " blocks²<br>"); } if (stats.waterArea > 0) { sb.append("Water or lava area: " + formatter.format(stats.waterArea) + " blocks²<br>"); if (stats.landArea > 0) { sb.append("Total surface area: " + formatter.format(stats.landArea + stats.waterArea) + " blocks²<br>"); } } final long totalBlocks = stats.surfaceArea * world.getMaxHeight(); if (duration > 0) { sb.append("Generated " + formatter.format(totalBlocks) + " blocks, or " + formatter.format(totalBlocks / duration) + " blocks per second<br>"); final long kbPerSecond = stats.size / duration / 1024; sb.append("Map size: " + formatter.format(stats.size / 1024 / 1024) + " MB, or " + ((kbPerSecond < 1024) ? (formatter.format(kbPerSecond) + " KB") : (formatter.format(kbPerSecond / 1024) + " MB")) + " per second"); } else { sb.append("Generated " + formatter.format(totalBlocks) + " blocks<br>"); sb.append("Map size: " + formatter.format(stats.size / 1024 / 1024) + " MB"); } } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { multiProgressComponent1 = new org.pepsoft.util.swing.MultiProgressComponent(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setTitle("Exporting"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addComponent(multiProgressComponent1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(multiProgressComponent1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap()) ); pack(); }// </editor-fold>//GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables private org.pepsoft.util.swing.MultiProgressComponent multiProgressComponent1; // End of variables declaration//GEN-END:variables private final World2 world; private final String name; private final File baseDir; private volatile File backupDir; private static final long serialVersionUID = 1L; }