001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Dennis Ushakov
019: * @version $Revision$
020: */package javax.swing.colorchooser;
021:
022: import java.awt.BorderLayout;
023: import java.awt.Color;
024: import java.awt.Dimension;
025: import java.awt.Graphics;
026: import java.awt.event.MouseEvent;
027:
028: import java.util.Arrays;
029:
030: import javax.swing.Icon;
031: import javax.swing.JLabel;
032: import javax.swing.JPanel;
033: import javax.swing.UIManager;
034: import javax.swing.event.MouseInputAdapter;
035:
036: class SwatchesPanel extends AbstractColorChooserPanel {
037: private final static int MAIN_SWATCH_WIDTH = 31;
038: private final static int MAIN_SWATCH_HEIGHT = 9;
039: private final static int RECENT_SWATCH_WIDTH = 5;
040: private final static int RECENT_SWATCH_HEIGHT = 7;
041:
042: private final static Color[][] MAIN_SWATCH_COLORS = createColors();
043: private Dimension swatchSize;
044: private Dimension recentSwatchSize;
045: private SwatchPanel recentPanel;
046: private SwatchPanel swatchPanel;
047:
048: private final class SwatchPanelMouseInputAdapter extends
049: MouseInputAdapter {
050: private SwatchPanel panel;
051:
052: SwatchPanelMouseInputAdapter(final SwatchPanel panel) {
053: this .panel = panel;
054: }
055:
056: public void mouseClicked(final MouseEvent e) {
057: getColorSelectionModel().setSelectedColor(
058: panel.getColorAtLocation(e.getX(), e.getY(), true));
059: }
060:
061: public void mouseMoved(final MouseEvent e) {
062: Color color = panel.getColorAtLocation(e.getX(), e.getY(),
063: false);
064: panel.setToolTipText(color.getRed() + ", "
065: + color.getGreen() + ", " + color.getBlue());
066: }
067: }
068:
069: private static class SwatchPanel extends JPanel {
070: int oneColorWidth;
071: int oneColorHeight;
072:
073: private Color[][] colors;
074: private SwatchPanel recentPanel;
075:
076: public SwatchPanel(final Color[][] colors,
077: final Dimension oneColorSize) {
078: this (colors, null, oneColorSize);
079: }
080:
081: public SwatchPanel(final Color[][] colors,
082: final SwatchPanel recentPanel,
083: final Dimension oneColorSize) {
084: this .colors = colors;
085: this .recentPanel = recentPanel;
086: this .oneColorHeight = oneColorSize.height;
087: this .oneColorWidth = oneColorSize.width;
088: }
089:
090: public Dimension getPreferredSize() {
091: return new Dimension((oneColorWidth + 1) * colors.length
092: + 1, (oneColorHeight + 1) * colors[0].length + 1);
093: }
094:
095: public Dimension getMinimumSize() {
096: return getPreferredSize();
097: }
098:
099: public Color getColorAtLocation(final int x, final int y,
100: final boolean updateRecent) {
101: int colorsX = x / (oneColorWidth + 1);
102: colorsX = colorsX < colors.length ? colorsX
103: : colors.length - 1;
104: int colorsY = y / (oneColorHeight + 1);
105: colorsY = colorsY < colors[0].length ? colorsY
106: : colors[0].length - 1;
107: Color result = colors[colorsX][colorsY];
108: if (updateRecent && recentPanel != null) {
109: recentPanel.addColor(result);
110: }
111: return result;
112: }
113:
114: protected void paintComponent(final Graphics graphics) {
115: Color oldColor = graphics.getColor();
116:
117: for (int i = 0; i < colors.length; i++) {
118: for (int j = 0; j < colors[i].length; j++) {
119: Color paintColor = colors[i][j] != null ? colors[i][j]
120: : this .getBackground();
121: graphics.setColor(paintColor);
122: graphics.fillRect((oneColorWidth + 1) * i,
123: (oneColorHeight + 1) * j, oneColorWidth,
124: oneColorHeight);
125: graphics.setColor(Color.WHITE);
126: graphics
127: .draw3DRect((oneColorWidth + 1) * i,
128: (oneColorHeight + 1) * j,
129: oneColorWidth - 1,
130: oneColorHeight - 1, true);
131: }
132: }
133: graphics.setColor(oldColor);
134: }
135:
136: private void addColor(final Color color) {
137: for (int i = colors.length * colors[0].length - 2; i >= 0; i--) {
138: colors[(i + 1) % colors.length][(i + 1) / colors.length] = colors[i
139: % colors.length][i / colors.length];
140: }
141: colors[0][0] = color;
142: repaint();
143: }
144: }
145:
146: public String getDisplayName() {
147: return UIManager.getString("ColorChooser.swatchesNameText");
148: }
149:
150: public Icon getSmallDisplayIcon() {
151: return null;
152: }
153:
154: public Icon getLargeDisplayIcon() {
155: return null;
156: }
157:
158: public void updateChooser() {
159:
160: }
161:
162: protected void buildChooser() {
163: mnemonic = Integer.parseInt(UIManager
164: .getString("ColorChooser.swatchesMnemonic"));
165: displayedMnemonicIndex = Integer
166: .parseInt(UIManager
167: .getString("ColorChooser.swatchesDisplayedMnemonicIndex"));
168:
169: swatchSize = UIManager
170: .getDimension("ColorChooser.swatchesSwatchSize");
171: recentSwatchSize = UIManager
172: .getDimension("ColorChooser.swatchesRecentSwatchSize");
173:
174: JPanel right = new JPanel(new BorderLayout());
175: recentPanel = new SwatchPanel(createRecentColors(), null,
176: recentSwatchSize);
177: MouseInputAdapter swatchMouseAdapter = new SwatchPanelMouseInputAdapter(
178: recentPanel);
179: recentPanel.addMouseListener(swatchMouseAdapter);
180: recentPanel.addMouseMotionListener(swatchMouseAdapter);
181:
182: right.add(BorderLayout.CENTER, new JLabel(UIManager
183: .getString("ColorChooser.swatchesRecentText")));
184: right.add(BorderLayout.SOUTH, recentPanel);
185:
186: swatchPanel = new SwatchPanel(MAIN_SWATCH_COLORS, recentPanel,
187: swatchSize);
188: swatchMouseAdapter = new SwatchPanelMouseInputAdapter(
189: swatchPanel);
190: swatchPanel.addMouseListener(swatchMouseAdapter);
191: swatchPanel.addMouseMotionListener(swatchMouseAdapter);
192:
193: JPanel fullPanel = new JPanel();
194: fullPanel.add(swatchPanel);
195: fullPanel.add(right);
196: this .add(fullPanel);
197: }
198:
199: // The intention of this algorithm is to cover the entire color-spectrum
200: // to fill swatcher cells uniformely
201: private static Color[][] createColors() {
202: Color[][] colors = new Color[MAIN_SWATCH_WIDTH][MAIN_SWATCH_HEIGHT];
203: for (int i = 0; i < colors[0].length; i++) {
204: colors[0][i] = Color.getHSBColor(1.f, 0.f, 1.f - (float) i
205: / colors[0].length);
206: }
207: for (int i = 1; i < colors.length; i++) {
208: for (int j = 0; j < colors[i].length / 2; j++) {
209: colors[i][j] = Color.getHSBColor(
210: (.5f + (float) (i - 1 - colors.length)
211: / (colors.length - 1)), 2.f
212: * (j + 1.5f) / colors[i].length, 1.f);
213: }
214: for (int j = colors[i].length / 2; j < colors[i].length; j++) {
215: colors[i][j] = Color.getHSBColor(
216: (.5f + (float) (i - 1 - colors.length)
217: / (colors.length - 1)), 1.f, 1.5f
218: * (colors[i].length - j + .3f)
219: / (colors[i].length - 1));
220: }
221: }
222: return colors;
223: }
224:
225: private static Color[][] createRecentColors() {
226: final Color[][] colors = new Color[RECENT_SWATCH_WIDTH][RECENT_SWATCH_HEIGHT];
227: final Object propertyValue = UIManager
228: .get("ColorChooser.swatchesDefaultRecentColor");
229: final Color defaultColor = propertyValue instanceof Color ? (Color) propertyValue
230: : Color.BLACK;
231: for (Color[] cols : colors)
232: Arrays.fill(cols, defaultColor);
233:
234: return colors;
235: }
236: }
|