/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2009-2012, Open Source Geospatial Foundation (OSGeo) * (C) 2009-2012, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.internal.wizard; import java.io.IOException; import java.util.Map; import java.awt.Dimension; import java.awt.BorderLayout; import java.util.logging.Level; import javax.swing.JPanel; import javax.swing.JComponent; import javax.swing.BorderFactory; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.jdesktop.swingx.JXLabel; import org.netbeans.spi.wizard.WizardController; import org.geotoolkit.image.io.mosaic.TileManager; import org.geotoolkit.gui.swing.LoggingPanel; import org.geotoolkit.gui.swing.image.MosaicChooser; import org.geotoolkit.gui.swing.image.MosaicBuilderEditor; import org.geotoolkit.gui.swing.image.MultiColorChooser; import org.geotoolkit.resources.Vocabulary; import org.geotoolkit.resources.Wizards; /** * Guides the user through the steps of creating a set of * {@linkplain org.geotoolkit.image.io.mosaic.Tile tiles}. * * @author Martin Desruisseaux (Geomatys) * @author Cédric Briançon (Geomatys) * @version 3.11 * * @since 3.00 * @module */ public final class MosaicWizard extends AbstractWizard { /** * The default size for content panes. */ private static final Dimension SIZE = new Dimension(800, 400); /** * The ID of the chooser for the input mosaic, which is the first step in the wizard. */ static final String SELECT = "SELECT"; /** * The ID for the editor of the layout of the mosaic to create. */ static final String LAYOUT = "LAYOUT"; /** * The ID for the panel selecting the colors to make transparent. */ static final String COLORS = "COLORS"; /** * The ID for the panel asking confirmation. */ static final String CONFIRM = "CONFIRM"; /** * The last line displayed in the last panel. */ private static final String CONFIRM_LABEL = "CONFIRM_LABEL"; /** * {@code true} if the input mosaic changed. This is set to {@code true} if the * first panel is revisited, in order to tells the second panel that it needs to * configure itself for a new input mosaic. * <p> * If the user is navigating back from the third panel, then the second panel is * not changed. */ private boolean inputChanged; /** * Creates a new wizard. */ public MosaicWizard() { super(Wizards.format(Wizards.Keys.MosaicTitle), new String[] { SELECT, LAYOUT, COLORS, CONFIRM }, new String[] { Wizards.format(Wizards.Keys.SelectSourceTiles), Wizards.format(Wizards.Keys.DefinePyramidTiling), Wizards.format(Wizards.Keys.RemoveOpaqueBorder), Vocabulary.format(Vocabulary.Keys.Confirm) }); } /** * Creates a panel that represents a named step in the wizard. * * @param controller The object which controls whether the Next/Finish buttons in the wizard are enabled. * @param id The name of the step, one of the array of steps passed in the constructor. * @param settings A Map containing settings from earlier steps in the wizard. * @return The component that should be displayed in the center of the wizard. */ @Override @SuppressWarnings("rawtypes") protected JComponent createPanel(final WizardController controller, final String id, final Map settings) { JComponent component; switch (id) { // ------------------------------------------------------------------- // Panel 1: Select source tiles // ------------------------------------------------------------------- case SELECT: { final class Chooser extends MosaicChooser implements ChangeListener { Chooser() { addChangeListener(this); stateChanged(null); // Force the call to controller.setProblem("..."), } private static final long serialVersionUID = -6696539336904269650L; @Override public void stateChanged(final ChangeEvent event) { final TileManager[] tiles = getSelectedTiles(); final String problem; switch (tiles.length) { case 0: problem = Wizards.format(Wizards.Keys.NoSelectedTiles); break; case 1: problem = null; break; // We can process default: problem = Wizards.format(Wizards.Keys.InvalidMosaicLayout); break; } controller.setProblem(problem); } } component = new Chooser(); addSetting(settings, SELECT, component); break; } // ------------------------------------------------------------------- // Panel 2: Define pyramid tiling // ------------------------------------------------------------------- case LAYOUT: { @SuppressWarnings("serial") final class Editor extends MosaicBuilderEditor { Editor() { } Editor(final TileManager... input) throws IOException { super(input); } /** Invoked when the values in the form changed. */ @Override protected void plotEfficiency(final long delay) { controller.setProblem(Wizards.format(Wizards.Keys.CalculationProgessing)); super.plotEfficiency(delay); } /** Invoked on success. */ @Override public void done(final TileManager output) { super.done(output); controller.setProblem(null); } /** Invoked on failure - can't move to the next step. */ @Override public void failed(final Throwable exception) { super.failed(exception); controller.setProblem(exception.getLocalizedMessage()); } } final MosaicChooser chooser = (MosaicChooser) settings.get(SELECT); try { component = new Editor(chooser.getSelectedTiles()); } catch (IOException exception) { component = new Editor(); controller.setProblem(exception.toString()); } addSetting(settings, LAYOUT, component); break; } // ------------------------------------------------------------------- // Panel 3: Remove opaque border // ------------------------------------------------------------------- case COLORS: { component = new MultiColorChooser(); addSetting(settings, COLORS, component); break; } // ------------------------------------------------------------------- // Panel 4: Confirm // ------------------------------------------------------------------- case CONFIRM: { final LoggingPanel logging = new LoggingPanel("org.geotoolkit.image.io.mosaic"); logging.setColumnVisible(LoggingPanel.Column.LOGGER, false); logging.setColumnVisible(LoggingPanel.Column.CLASS, false); logging.setColumnVisible(LoggingPanel.Column.METHOD, false); logging.setColumnVisible(LoggingPanel.Column.LEVEL, false); logging.getHandler().setLevel(Level.FINE); // The level used by MosaicImageWriter. final JXLabel label = new JXLabel(Wizards.format(Wizards.Keys.EnoughInformation)); label.setLineWrap(true); final JPanel panel = new JPanel(new BorderLayout()); panel.add(logging, BorderLayout.CENTER); panel.add(label, BorderLayout.SOUTH); component = panel; addSetting(settings, CONFIRM, logging); addSetting(settings, CONFIRM_LABEL, label); break; } default: { throw new IllegalArgumentException(id); // Should never happen. } } component.setPreferredSize(SIZE); component.setBorder(BorderFactory.createEmptyBorder(6, 15, 9, 15)); return component; } /** * Invoked when a panel is being revisited one more time. * * @param id The name of the step, one of the array of steps passed in the constructor. * @param controller The object which controls whether the Next/Finish buttons in the wizard are enabled. * @param settings A Map containing settings from earlier steps in the wizard. * @param panel The panel being recycled. */ @Override @SuppressWarnings("rawtypes") protected void recycleExistingPanel(final String id, final WizardController controller, final Map settings, final JComponent panel) { switch (id) { case SELECT: { inputChanged = true; break; } case LAYOUT: { if (inputChanged) { inputChanged = false; final MosaicChooser chooser = (MosaicChooser) settings.get(SELECT); final MosaicBuilderEditor editor = (MosaicBuilderEditor) panel; try { editor.initializeForTiles(chooser.getSelectedTiles()); } catch (IOException exception) { controller.setProblem(exception.toString()); return; } } break; } } controller.setProblem(null); } /** * Invoked when the user cancel the wizard. * * @param settings The settings provided by the user. * @return {@code true} in all cases, for allowing cancelation. */ @Override @SuppressWarnings("rawtypes") public boolean cancel(final Map settings) { final LoggingPanel logging = (LoggingPanel) settings.get(CONFIRM); if (logging != null) { logging.dispose(); } return super.cancel(settings); } /** * Invoked when the user finished to go through wizard steps. * * @param settings The settings provided by the user. * @return The object which will create the mosaic. */ @Override @SuppressWarnings("rawtypes") protected Object finish(final Map settings) { final Wizards resources = Wizards.getResources(null); ((JXLabel) settings.get(CONFIRM_LABEL)).setText(resources.getMenuLabel(Wizards.Keys.CreatingMosaic)); return new MosaicCreator(); } }