package org.esa.snap.rcp.colormanip; import org.esa.snap.core.datamodel.ColorPaletteDef; import org.esa.snap.core.datamodel.ImageInfo; import org.esa.snap.core.image.ImageManager; import org.esa.snap.core.util.io.FileUtils; import org.esa.snap.core.util.math.Range; import javax.swing.ComboBoxModel; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.ListCellRenderer; import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.List; import java.util.Vector; class ColorPaletteChooser extends JComboBox<ColorPaletteChooser.ColorPaletteWrapper> { private final String DERIVED_FROM = "derived from"; private final String UNNAMED = "unnamed"; private boolean discreteDisplay; private boolean log10Display; public ColorPaletteChooser() { super(getPalettes()); setRenderer(createPaletteRenderer()); setEditable(false); } public void removeUserDefinedPalette() { if (getItemCount() > 0) { final String name = getItemAt(0).name; if (UNNAMED.equals(name) || name.startsWith(DERIVED_FROM)) { removeItemAt(0); } } } public ColorPaletteDef getSelectedColorPaletteDefinition() { final int selectedIndex = getSelectedIndex(); final ComboBoxModel<ColorPaletteWrapper> model = getModel(); final ColorPaletteWrapper colorPaletteWrapper = model.getElementAt(selectedIndex); final ColorPaletteDef cpd = colorPaletteWrapper.cpd; cpd.getFirstPoint().setLabel(colorPaletteWrapper.name); return cpd; } public void setSelectedColorPaletteDefinition(ColorPaletteDef cpd) { removeUserDefinedPalette(); final ComboBoxModel<ColorPaletteWrapper> model = getModel(); for (int i = 0; i < model.getSize(); i++) { if (model.getElementAt(i).cpd.equals(cpd)) { setSelectedIndex(i); return; } } setUserDefinedPalette(cpd); } public void reloadPalettes() { setModel(new DefaultComboBoxModel<>(getPalettes())); repaint(); } private void setUserDefinedPalette(ColorPaletteDef userPalette) { final String suffix = userPalette.getFirstPoint().getLabel(); final String name; if (suffix != null && suffix.trim().length() > 0) { name = DERIVED_FROM + " " + suffix.trim(); } else { name = UNNAMED; } final ColorPaletteWrapper item = new ColorPaletteWrapper(name, userPalette); insertItemAt(item, 0); setSelectedIndex(0); } private static Vector<ColorPaletteWrapper> getPalettes() { final List<ColorPaletteDef> defList = ColorPaletteManager.getDefault().getColorPaletteDefList(); final Vector<ColorPaletteWrapper> paletteWrappers = new Vector<>(); for (ColorPaletteDef colorPaletteDef : defList) { final String nameFor = getNameForWithoutExtension(colorPaletteDef); paletteWrappers.add(new ColorPaletteWrapper(nameFor, colorPaletteDef)); } return paletteWrappers; } private static String getNameForWithoutExtension(ColorPaletteDef colorPaletteDef) { final String nameFor = ColorPaletteManager.getDefault().getNameFor(colorPaletteDef); if (nameFor.toLowerCase().endsWith(".cpd")) { return nameFor.substring(0, nameFor.length() - 4); } else { return nameFor; } } private ListCellRenderer<ColorPaletteWrapper> createPaletteRenderer() { return new ListCellRenderer<ColorPaletteWrapper>() { @Override public Component getListCellRendererComponent(JList<? extends ColorPaletteWrapper> list, ColorPaletteWrapper value, int index, boolean isSelected, boolean cellHasFocus) { final Font font = getFont(); final Font smaller = font.deriveFont(font.getSize() * 0.85f); final JLabel nameComp = new JLabel(value.name); nameComp.setFont(smaller); final ColorPaletteDef cpd = value.cpd; final JLabel rampComp = new JLabel(" ") { @Override public void paint(Graphics g) { super.paint(g); drawPalette((Graphics2D) g, cpd, g.getClipBounds().getSize()); } }; final JPanel palettePanel = new JPanel(new BorderLayout(0, 2)); palettePanel.add(nameComp, BorderLayout.NORTH); palettePanel.add(rampComp, BorderLayout.CENTER); return palettePanel; } }; } private void drawPalette(Graphics2D g2, ColorPaletteDef colorPaletteDef, Dimension paletteDim) { final int width = paletteDim.width; final int height = paletteDim.height; final ColorPaletteDef cpdCopy = colorPaletteDef.createDeepCopy(); cpdCopy.setDiscrete(discreteDisplay); cpdCopy.setNumColors(width); final ImageInfo imageInfo = new ImageInfo(cpdCopy); imageInfo.setLogScaled(log10Display); Color[] colorPalette = ImageManager.createColorPalette(imageInfo); g2.setStroke(new BasicStroke(1.0f)); for (int x = 0; x < width; x++) { g2.setColor(colorPalette[x]); g2.drawLine(x, 0, x, height); } } public void setLog10Display(boolean log10Display) { this.log10Display = log10Display; repaint(); } public void setDiscreteDisplay(boolean discreteDisplay) { this.discreteDisplay = discreteDisplay; repaint(); } public Range getRangeFromFile() { final ComboBoxModel<ColorPaletteWrapper> model = getModel(); final int selectedIndex = getSelectedIndex(); final ColorPaletteWrapper paletteWrapper = model.getElementAt(selectedIndex); String name = paletteWrapper.name; final ColorPaletteDef cpd; if (name.startsWith(DERIVED_FROM)) { name = name.substring(DERIVED_FROM.length()).trim(); if (name.toLowerCase().endsWith(".cpd")) { name = FileUtils.getFilenameWithoutExtension(name); } cpd = findColorPalette(name); } else { cpd = paletteWrapper.cpd; } return new Range(cpd.getMinDisplaySample(), cpd.getMaxDisplaySample()); } private ColorPaletteDef findColorPalette(String name) { final ComboBoxModel<ColorPaletteWrapper> model = getModel(); for (int i = 0; i < model.getSize(); i++) { final ColorPaletteWrapper paletteWrapper = model.getElementAt(i); if (paletteWrapper.name.equals(name)) { return paletteWrapper.cpd; } } return null; } public static final class ColorPaletteWrapper { public final String name; public final ColorPaletteDef cpd; private ColorPaletteWrapper(String name, ColorPaletteDef cpd) { this.name = name; this.cpd = cpd; } } }