package org.esa.snap.ui.color;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.WindowConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.colorchooser.AbstractColorChooserPanel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Vector;
/**
* A color chooser panel.
*
* @author Norman Fomferra
* @author Marco Peters
* @since SNAP 2.0
*/
public class ColorChooserPanel extends JPanel {
public static final String SELECTED_COLOR_PROPERTY = "selectedColor";
static final Color TRANSPARENCY = new Color(0, 0, 0, 0);
private static final int GAP = 2;
private Color selectedColor;
public ColorChooserPanel() {
this(Color.WHITE);
}
public ColorChooserPanel(Color selectedColor) {
super(new BorderLayout(GAP, GAP));
setBorder(new EmptyBorder(GAP, GAP, GAP, GAP));
setSelectedColor(selectedColor);
JButton noneButton = new JButton("None");
noneButton.addActionListener(e -> {
setSelectedColor(TRANSPARENCY);
});
JButton moreButton = new JButton("More...");
moreButton.addActionListener(e -> {
Color color = showMoreColorsDialog();
if (color != null) {
setSelectedColor(color);
}
});
add(noneButton, BorderLayout.NORTH);
add(createColorPicker(), BorderLayout.CENTER);
add(moreButton, BorderLayout.SOUTH);
// todo - use colors from popup menu LAF
setBackground(Color.WHITE);
}
public Color getSelectedColor() {
return selectedColor;
}
public void setSelectedColor(Color selectedColor) {
Color oldValue = this.selectedColor;
this.selectedColor = selectedColor;
firePropertyChange(SELECTED_COLOR_PROPERTY, oldValue, this.selectedColor);
}
protected JComponent createColorPicker() {
Color[] colors = {Color.BLACK,
Color.DARK_GRAY,
Color.GRAY,
Color.LIGHT_GRAY,
Color.WHITE,
Color.CYAN,
Color.BLUE,
Color.MAGENTA,
Color.YELLOW,
Color.ORANGE,
Color.RED,
Color.PINK,
Color.GREEN};
JPanel colorsPanel = new JPanel(new GridLayout(-1, 6, 4, 4));
colorsPanel.setOpaque(false);
for (Color color : colors) {
ColorLabel colorLabel = new ColorLabel(color);
colorLabel.setDisplayName(ColorCodes.getName(color));
colorLabel.setHoverEnabled(true);
colorLabel.setMaximumSize(colorLabel.getPreferredSize());
colorLabel.setMinimumSize(colorLabel.getPreferredSize());
colorLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
setSelectedColor(colorLabel.getColor());
}
});
colorsPanel.add(colorLabel);
}
return colorsPanel;
}
protected Color showMoreColorsDialog() {
JColorChooser colorChooser = new JColorChooser(getSelectedColor());
AbstractColorChooserPanel[] oldChooserPanels = colorChooser.getChooserPanels();
AbstractColorChooserPanel[] newChooserPanels = new AbstractColorChooserPanel[oldChooserPanels.length + 1];
System.arraycopy(oldChooserPanels, 0, newChooserPanels, 1, oldChooserPanels.length);
newChooserPanels[0] = new MyAbstractColorChooserPanel();
colorChooser.setChooserPanels(newChooserPanels);
ColorTracker colorTracker = new ColorTracker(colorChooser);
JDialog dialog = JColorChooser.createDialog(this, "Select Colour", true, colorChooser, colorTracker, null);
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
return colorTracker.getColor();
}
private static class MyAbstractColorChooserPanel extends AbstractColorChooserPanel implements ListSelectionListener {
private JList<String> colorList;
public MyAbstractColorChooserPanel() {
}
@Override
public void updateChooser() {
Color selectedColor = getColorSelectionModel().getSelectedColor();
if (selectedColor != null) {
int i = ColorCodes.indexOf(selectedColor);
if (i >= 0) {
colorList.setSelectedIndex(i);
}
}
}
@Override
protected void buildChooser() {
colorList = new JList<>(new Vector<>(ColorCodes.getNames()));
DefaultListCellRenderer cellRenderer = new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
setOpaque(true);
Color color = ColorCodes.getColor(value.toString());
int max = Math.max(color.getRed(), Math.max(color.getGreen(), color.getBlue()));
setForeground(max < 160 ? Color.WHITE : Color.BLACK);
setBackground(color);
setBorder(new EmptyBorder(5, 5, 5, 5));
setFont(getFont().deriveFont(14f));
return this;
}
};
colorList.setCellRenderer(cellRenderer);
colorList.addListSelectionListener(this);
setLayout(new BorderLayout());
setBorder(new EmptyBorder(5, 5, 5, 5));
add(new JScrollPane(colorList), BorderLayout.CENTER);
}
@Override
public void valueChanged(ListSelectionEvent e) {
int selectedIndex = colorList.getSelectedIndex();
Color color = ColorCodes.getColor(selectedIndex);
getColorSelectionModel().setSelectedColor(color);
}
@Override
public String getDisplayName() {
return "HTML Color Codes";
}
@Override
public Icon getSmallDisplayIcon() {
return null;
}
@Override
public Icon getLargeDisplayIcon() {
return null;
}
}
private static class ColorTracker implements ActionListener {
private JColorChooser colorChooser;
private Color color;
public ColorTracker(JColorChooser colorChooser) {
this.colorChooser = colorChooser;
}
public Color getColor() {
return color;
}
@Override
public void actionPerformed(ActionEvent e) {
color = colorChooser.getColor();
}
}
}