/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2010-2012, Open Source Geospatial Foundation (OSGeo) * (C) 2010-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.coverage; import java.awt.Color; import java.io.IOException; import java.io.Serializable; import java.util.Set; import java.util.Arrays; import java.util.Vector; import java.util.logging.Level; import java.util.logging.LogRecord; import javax.swing.ComboBoxModel; import javax.swing.DefaultComboBoxModel; import org.apache.sis.util.logging.Logging; import static org.apache.sis.util.collection.Containers.isNullOrEmpty; import org.geotoolkit.image.color.ColorUtilities; import org.geotoolkit.image.palette.PaletteFactory; /** * The name of a color palette, as an item to be provided in a {@link javax.swing.JComboBox}. * The ARGB colors are loaded when first needed and cached for future reuse. * * @author Martin Desruisseaux (Geomatys) * @version 3.14 * * @since 3.14 (derived from 3.13) * @module */ @SuppressWarnings("serial") public final class ColorPalette implements Serializable { /** * The name of the color palette. */ public final String paletteName; /** * The colors, loaded when first needed. */ private transient Color[] colors; /** * Creates a new {@code ColorPalette} for the given color palette name. * * @param paletteName The color palette name. */ public ColorPalette(final String paletteName) { this.paletteName = paletteName; } /** * Returns the colors. This method loads the colors when first needed. * * @param factory The factory to use for loading the colors. * @return The colors for the palette name given at construction time. */ public Color[] getColors(final PaletteFactory factory) { if (colors == null) { try { colors = factory.getColors(paletteName); } catch (IOException e) { Logging.log(PaletteFactory.class, "getColors", new LogRecord(Level.WARNING, e.getLocalizedMessage())); } if (colors == null) { colors = new Color[] {Color.BLACK, Color.WHITE}; } } return colors.clone(); } /** * Returns a string representation of the color palette, suitable for use in a GUI. */ @Override public String toString() { return paletteName; } /** * Returns the {@code ColorPalette}s available for the given factory. * The palettes are returned in a {@link ComboBoxModel} for usage by * {@link org.geotoolkit.gui.swing.image.PaletteComboBox}. * * @param factory The factory to use for getting the choices. * @return The choices, or {@code null} if none. */ public static ComboBoxModel<ColorPalette> getChoices(final PaletteFactory factory) { final Set<String> names = factory.getAvailableNames(); if (isNullOrEmpty(names)) { return null; } final Vector<ColorPalette> items = new Vector<>(names.size()); for (final String n : names) { items.add(new ColorPalette(n)); } return new DefaultComboBoxModel<>(items); } /** * Finds the name of a palette having the given colors. * * @param colors The colors for which to find the palette name. * @param factory The factory to use for fetching the colors from their name, * or {@code null} for the {@linkplain PaletteFactory#getDefault() default one}. * @param choices A list of palettes to use for inferring the palettes names, * or {@code null} if none. This can be used for the common case where * this list is already available from the {@link SampleDimensionPanel} GUI. * @return The name of the color palette, or {@code null} if no match were found or * if the color is fully transparent. */ public static String findName(final Color[] colors, ComboBoxModel<ColorPalette> choices, PaletteFactory factory) { /* * Determines the palette name or RGB code. In the simplest * case, we have a single Color object to format as "#RRGGBB". */ if (colors.length == 1) { final Color singleton = colors[0]; if (singleton != null && singleton.getAlpha() != 0) { return ColorUtilities.toString(singleton); } } else if (colors.length != 0) { /* * More complex case. Compares the colors against every palettes * defined in the given list. We will create the list ourself if * it was not explicitly provided. */ if (factory == null) { factory = PaletteFactory.getDefault(); } if (choices == null) { choices = getChoices(factory); } int index = choices.getSize(); while (--index >= 0) { final ColorPalette candidate = choices.getElementAt(index); if (Arrays.equals(colors, candidate.getColors(factory))) { return candidate.paletteName; } } } return null; } }