// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.gui.layer; import static org.openstreetmap.josm.gui.help.HelpUtil.ht; import static org.openstreetmap.josm.tools.I18n.tr; import java.awt.Color; import java.awt.Component; import java.awt.event.ActionEvent; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JColorChooser; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.data.preferences.AbstractProperty; import org.openstreetmap.josm.gui.dialogs.LayerListDialog; import org.openstreetmap.josm.gui.layer.Layer.LayerAction; import org.openstreetmap.josm.gui.layer.Layer.MultiLayerAction; import org.openstreetmap.josm.tools.CheckParameterUtil; import org.openstreetmap.josm.tools.ImageProvider; public class CustomizeColor extends AbstractAction implements LayerAction, MultiLayerAction { private final transient List<AbstractProperty<Color>> colors; /** * Constructs a new {@code CustomizeColor} for a given list of layers. * @param l list of layers */ public CustomizeColor(List<Layer> l) { super(tr("Customize Color"), ImageProvider.get("colorchooser")); colors = l.stream().map(Layer::getColorProperty).collect(Collectors.toList()); CheckParameterUtil.ensureThat(colors.stream().allMatch(Objects::nonNull), "All layers must have colors."); putValue("help", ht("/Action/LayerCustomizeColor")); } /** * Constructs a new {@code CustomizeColor} for a single layer. * @param l layer */ public CustomizeColor(Layer l) { this(Collections.singletonList(l)); } @Override public boolean supportLayers(List<Layer> layers) { return layers.stream().allMatch(l -> l.getColorProperty() != null); } @Override public Component createMenuComponent() { return new JMenuItem(this); } @Override public Action getMultiLayerAction(List<Layer> layers) { return new CustomizeColor(layers); } @Override public void actionPerformed(ActionEvent e) { Color cl = colors.stream().map(AbstractProperty::get).filter(Objects::nonNull).findAny().orElse(Color.GRAY); JColorChooser c = new JColorChooser(cl); Object[] options = new Object[]{tr("OK"), tr("Cancel"), tr("Default")}; int answer = JOptionPane.showOptionDialog( Main.parent, c, tr("Choose a color"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0] ); switch (answer) { case 0: colors.stream().forEach(prop -> prop.put(c.getColor())); break; case 1: return; case 2: colors.stream().forEach(prop -> prop.put(null)); break; } // TODO: Make the layer dialog listen to property change events so that this is not needed any more. LayerListDialog.getInstance().repaint(); } }