/* * Copyright (C) 2007 Clam <clamisgood@gmail.com> * Copyright (C) 2007, 2011 IsmAvatar <IsmAvatar@gmail.com> * Copyright (C) 2009 Quadduc <quadduc@gmail.com> * Copyright (C) 2015 Robert B. Colton * * This file is part of LateralGM. * LateralGM is free software and comes with ABSOLUTELY NO WARRANTY. * See LICENSE for details. */ package org.lateralgm.components; import static javax.swing.GroupLayout.PREFERRED_SIZE; import java.awt.Color; import java.awt.Graphics; import java.awt.ItemSelectable; import java.awt.Rectangle; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.text.ParseException; import javax.swing.BorderFactory; import javax.swing.GroupLayout; import javax.swing.JColorChooser; import javax.swing.JFormattedTextField; import javax.swing.JPanel; import javax.swing.GroupLayout.Alignment; import javax.swing.border.BevelBorder; import javax.swing.text.MaskFormatter; import org.lateralgm.main.LGM; import org.lateralgm.main.Util; import org.lateralgm.messages.Messages; import org.lateralgm.util.PropertyEditor; import org.lateralgm.util.PropertyLink; import org.lateralgm.util.PropertyMap; import org.lateralgm.util.PropertyMap.PropertyUpdateEvent; public class ColorSelect extends JPanel implements ItemSelectable,PropertyEditor<Color> { private static final long serialVersionUID = 1L; private Color selectedColor; // If false, return always 255. Used for the instance's color. private boolean returnAlpha = true; private JPanel colorPanel; private JFormattedTextField textField; private static BufferedImage transparentImage; public ColorSelect(Color col) { if (transparentImage == null) { transparentImage = Util.paintBackground(2, 2); } colorPanel = new JPanel() { /** * NOTE: Default UID generated, change if necessary. */ private static final long serialVersionUID = -948015130105405683L; @Override public void paint(Graphics g) { Rectangle clipBounds = g.getClipBounds(); g.drawImage(transparentImage, 0, 0, clipBounds.width, clipBounds.height, null); super.paint(g); } }; colorPanel.setBorder(BorderFactory.createSoftBevelBorder(BevelBorder.RAISED, Color.WHITE, Color.BLACK)); colorPanel.setBackground(col); // needed by some look and feels such as Quaqua colorPanel.setOpaque(true); colorPanel.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { colorPanel.setBorder(BorderFactory.createSoftBevelBorder(BevelBorder.LOWERED, Color.WHITE, Color.BLACK)); } @Override public void mouseReleased(MouseEvent e) { colorPanel.setBorder(BorderFactory.createSoftBevelBorder(BevelBorder.RAISED, Color.WHITE, Color.BLACK)); } @Override public void mouseClicked(MouseEvent e) { Color newcol = JColorChooser.showDialog(getParent(), Messages.getString("ColorSelect.CHOOSE_TITLE"), selectedColor); //$NON-NLS-1$ if (newcol != null) { setSelectedColor(newcol); fireItemChanged(); } } }); MaskFormatter formatter = new MaskFormatter(); formatter.setPlaceholder("FFFFFFFF"); //$NON-NLS-1$ formatter.setPlaceholderCharacter('F'); //$NON-NLS-1$ try { formatter.setMask("HHHHHHHH"); //$NON-NLS-1$ } catch (ParseException e) { // This should never occur because the format is correct // and this has been well tested. LGM.showDefaultExceptionHandler(e); } textField = new JFormattedTextField(formatter); textField.setColumns(8); textField.setText(Util.formatColortoHex(col)); textField.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { selectedColor = new Color(Integer.rotateRight( (int) Long.parseLong(textField.getText(),16),textField.getText().length()), true); colorPanel.setBackground(selectedColor); fireItemChanged(); } }); GroupLayout gl = new GroupLayout(this); gl.setAutoCreateGaps(true); gl.setAutoCreateContainerGaps(false); gl.setHorizontalGroup(gl.createSequentialGroup() /* */.addComponent(colorPanel, PREFERRED_SIZE, PREFERRED_SIZE, PREFERRED_SIZE) /* */.addComponent(textField, PREFERRED_SIZE, PREFERRED_SIZE, PREFERRED_SIZE) ); gl.setVerticalGroup(gl.createParallelGroup(Alignment.CENTER) /* */.addComponent(colorPanel, PREFERRED_SIZE, PREFERRED_SIZE, PREFERRED_SIZE) /* */.addComponent(textField) ); this.setLayout(gl); selectedColor = col; } @Override public int getBaseline(int width, int height) { return textField.getBaseline(width, height); } public ColorSelect() { this(Color.BLACK); } public ColorSelect(Color col, boolean returnAlpha) { this(col); this.returnAlpha = returnAlpha; } protected void fireItemChanged() { // Guaranteed to return a non-null array Object[] listeners = listenerList.getListenerList(); // Process the listeners last to first, notifying // those that are interested in this event ItemEvent e = new ItemEvent(this,ItemEvent.ITEM_STATE_CHANGED,selectedColor,ItemEvent.SELECTED); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ItemListener.class) { ((ItemListener) listeners[i + 1]).itemStateChanged(e); } } } public void setSelectedColor(Color selectedColor) { if (returnAlpha == false) selectedColor = new Color (selectedColor.getRed(),selectedColor.getGreen(), selectedColor.getBlue()); colorPanel.setBackground(selectedColor); textField.setText(Util.formatColortoHex(selectedColor)); this.selectedColor = selectedColor; } public Color getSelectedColor() { if (returnAlpha == true) { return selectedColor; } else { Color selectedColorWithoutAlpha = new Color (selectedColor.getRed(),selectedColor.getGreen(), selectedColor.getBlue()); return selectedColorWithoutAlpha; } } @Override public void addItemListener(ItemListener l) { listenerList.add(ItemListener.class,l); } @Override public Object[] getSelectedObjects() { return new Color[] { selectedColor }; } @Override public void removeItemListener(ItemListener l) { listenerList.remove(ItemListener.class,l); } public <K extends Enum<K>>PropertyLink<K,Color> getLink(PropertyMap<K> m, K k) { return new ColorSelectLink<K>(m,k); } private class ColorSelectLink<K extends Enum<K>> extends PropertyLink<K,Color> implements ItemListener { public ColorSelectLink(PropertyMap<K> m, K k) { super(m,k); reset(); addItemListener(this); } @Override protected void setComponent(Color c) { setSelectedColor(c); } @Override public void remove() { super.remove(); removeItemListener(this); } @Override public void updated(PropertyUpdateEvent<K> e) { editComponentIfChanged(selectedColor); } public void itemStateChanged(ItemEvent e) { if (selectedColor.equals(map.get(key))) return; editProperty(selectedColor); } } }