2
* @(#)ColorPicker.java 1.1 2006-03-05
4
* Copyright (c) 2005 Werner Randelshofer
5
* Staldenmattweg 2, Immensee, CH-6405, Switzerland.
8
* This software is the confidential and proprietary information of
9
* Werner Randelshofer. ("Confidential Information"). You shall not
10
* disclose such Confidential Information and shall use it only in
11
* accordance with the terms of the license agreement you entered into
12
* with Werner Randelshofer.
15
package org.pushingpixels.substance.internal.contrib.randelshofer.quaqua.colorchooser;
18
import java.awt.event.*;
19
import java.awt.image.BufferedImage;
20
import java.security.AccessControlException;
23
import javax.swing.colorchooser.AbstractColorChooserPanel;
24
import javax.swing.plaf.IconUIResource;
26
import org.pushingpixels.substance.api.SubstanceColorScheme;
27
import org.pushingpixels.substance.internal.utils.SubstanceImageCreator;
28
import org.pushingpixels.substance.internal.utils.icon.TransitionAwareIcon;
33
* @author Werner Randelshofer
34
* @version 1.1 2006-03-06 Abort picker when the user presses the Escape-Key. <br>
35
* 1.0 December 18, 2005 Created.
37
public class ColorPicker extends AbstractColorChooserPanel {
39
* This frame is constantly moved to the current location of the mouse. This
40
* ensures that we can trap mouse clicks while the picker cursor is showing.
41
* Also, by tying the picker cursor to this frame, we ensure that the picker
42
* cursor (the magnifying glass) is shown.
44
private Dialog pickerFrame;
46
private Timer pickerTimer;
49
* Holds the image of the picker cursor.
51
private BufferedImage cursorImage;
53
* Graphics object used for drawing on the cursorImage.
55
private Graphics2D cursorGraphics;
60
private Cursor pickerCursor;
63
* The hot spot of the cursor.
65
private Point hotSpot;
68
* Offset from the hot spot of the pickerCursor to the pixel that we want to
69
* pick. We can't pick the color at the hotSpot of the cursor, because this
70
* point is obscured by the pickerFrame.
72
private Point pickOffset;
75
* The magnifying glass image.
77
private BufferedImage magnifierImage;
80
* The robot is used for creating screen captures.
84
private Color previousColor = Color.white;
85
private Point previousLoc = new Point();
86
private Point pickLoc = new Point();
87
private Point captureOffset = new Point();
88
private Rectangle captureRect;
89
private final static Color transparentColor = new Color(0, true);
90
private Rectangle zoomRect;
91
private Rectangle glassRect;
94
* Creates a new instance.
96
public ColorPicker() {
97
// Try immediately to create a screen capture in order to fail quickly,
99
// we can't provide a color picker functionality.
102
robot.createScreenCapture(new Rectangle(0, 0, 1, 1));
103
} catch (AWTException e) {
104
throw new AccessControlException("Unable to capture screen");
110
* Gets the picker frame. If the frame does not yet exist, it is created
111
* along with all the other objects that are needed to make the picker work.
113
private Dialog getPickerFrame() {
114
if (pickerFrame == null) {
115
Window owner = SwingUtilities.getWindowAncestor(this);
116
if (owner instanceof Dialog) {
117
pickerFrame = new Dialog((Dialog) owner);
118
} else if (owner instanceof Frame) {
119
pickerFrame = new Dialog((Frame) owner);
121
pickerFrame = new Dialog(new JFrame());
124
pickerFrame.addMouseListener(new MouseAdapter() {
126
public void mousePressed(MouseEvent evt) {
131
public void mouseExited(MouseEvent evt) {
136
pickerFrame.addMouseMotionListener(new MouseMotionAdapter() {
138
public void mouseMoved(MouseEvent evt) {
142
pickerFrame.setSize(3, 3);
143
pickerFrame.setUndecorated(true);
144
pickerFrame.setAlwaysOnTop(true);
146
pickerFrame.addKeyListener(new KeyAdapter() {
148
public void keyPressed(KeyEvent e) {
149
switch (e.getKeyCode()) {
150
case KeyEvent.VK_ESCAPE:
153
case KeyEvent.VK_ENTER:
160
magnifierImage = (BufferedImage) UIManager
161
.get("ColorChooser.colorPickerMagnifier");
162
glassRect = (Rectangle) UIManager
163
.get("ColorChooser.colorPickerGlassRect");
164
zoomRect = (Rectangle) UIManager
165
.get("ColorChooser.colorPickerZoomRect");
166
hotSpot = (Point) UIManager.get("ColorChooser.colorPickerHotSpot");// new
169
captureRect = new Rectangle((Rectangle) UIManager
170
.get("ColorChooser.colorPickerCaptureRect"));
171
pickOffset = (Point) UIManager
172
.get("ColorChooser.colorPickerPickOffset");
173
captureOffset = new Point(captureRect.x, captureRect.y);
174
cursorImage = getGraphicsConfiguration().createCompatibleImage(
175
magnifierImage.getWidth(), magnifierImage.getHeight(),
176
Transparency.TRANSLUCENT);
177
cursorGraphics = cursorImage.createGraphics();
178
cursorGraphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
179
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
181
pickerTimer = new Timer(5, new ActionListener() {
183
public void actionPerformed(ActionEvent evt) {
192
* Updates the color picker.
194
protected void updatePicker() {
195
if (pickerFrame != null && pickerFrame.isShowing()) {
196
PointerInfo info = MouseInfo.getPointerInfo();
197
if (info == null) return; //pointer not on a graphics device
198
Point mouseLoc = info.getLocation();
199
pickerFrame.setLocation(mouseLoc.x - pickerFrame.getWidth() / 2,
200
mouseLoc.y - pickerFrame.getHeight() / 2);
202
pickLoc.x = mouseLoc.x + pickOffset.x;
203
pickLoc.y = mouseLoc.y + pickOffset.y;
205
if (pickLoc.x >= 0 && pickLoc.y >= 0) {
206
Color c = robot.getPixelColor(pickLoc.x, pickLoc.y);
207
if (!c.equals(previousColor) || !mouseLoc.equals(previousLoc)) {
209
previousLoc = mouseLoc;
211
captureRect.setLocation(mouseLoc.x + captureOffset.x,
212
mouseLoc.y + captureOffset.y);
213
if (captureRect.x >= 0 && captureRect.y >= 0) {
214
BufferedImage capture = robot
215
.createScreenCapture(captureRect);
217
// Clear the cursor graphics
218
cursorGraphics.setComposite(AlphaComposite.Src);
219
cursorGraphics.setColor(transparentColor);
220
cursorGraphics.fillRect(0, 0, cursorImage.getWidth(),
221
cursorImage.getHeight());
223
// Fill the area for the zoomed screen capture with a
224
// non-transparent color (any non-transparent color does
226
cursorGraphics.setColor(Color.red);
227
cursorGraphics.fillOval(glassRect.x, glassRect.y,
228
glassRect.width, glassRect.height);
230
// Paint the screen capture with a zoom factor of 5
231
cursorGraphics.setComposite(AlphaComposite.SrcIn);
232
cursorGraphics.drawImage(capture, zoomRect.x,
233
zoomRect.y, zoomRect.width, zoomRect.height,
236
// Draw the magnifying glass image
237
cursorGraphics.setComposite(AlphaComposite.SrcOver);
238
cursorGraphics.drawImage(magnifierImage, 0, 0, this);
240
// We need to create a new subImage. This forces that
241
// the color picker uses the new imagery.
242
BufferedImage subImage = cursorImage
243
.getSubimage(0, 0, cursorImage.getWidth(),
244
cursorImage.getHeight());
245
pickerFrame.setCursor(getToolkit().createCustomCursor(
246
cursorImage, hotSpot, "ColorPicker"));
254
* This method is called from within the constructor to initialize the form.
255
* WARNING: Do NOT modify this code. The content of this method is always
256
* regenerated by the Form Editor.
258
private void initComponents() {// GEN-BEGIN:initComponents
259
pickerButton = new javax.swing.JButton();
261
setLayout(new java.awt.BorderLayout());
263
pickerButton.setBorderPainted(false);
264
pickerButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
265
pickerButton.addActionListener(new java.awt.event.ActionListener() {
267
public void actionPerformed(java.awt.event.ActionEvent evt) {
272
add(pickerButton, java.awt.BorderLayout.CENTER);
274
}// GEN-END:initComponents
276
private void pickBegin(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_pickBegin
279
getPickerFrame().setVisible(true);
280
}// GEN-LAST:event_pickBegin
282
protected void pickFinish() {
284
pickerFrame.setVisible(false);
285
PointerInfo info = MouseInfo.getPointerInfo();
286
if (info == null) return; //pointer not on a graphics device
288
Point loc = info.getLocation();
289
Color c = robot.getPixelColor(loc.x + pickOffset.x, loc.y
291
getColorSelectionModel().setSelectedColor(c);
294
protected void pickCancel() {
296
pickerFrame.setVisible(false);
300
protected void buildChooser() {
302
pickerButton.setIcon(new TransitionAwareIcon(pickerButton,
303
new TransitionAwareIcon.Delegate() {
305
public Icon getColorSchemeIcon(SubstanceColorScheme scheme) {
306
return new IconUIResource(SubstanceImageCreator
307
.getSearchIcon(15, scheme, pickerButton
308
.getComponentOrientation()
311
}, "ColorChooser.colorPickerIcon"));
315
public String getDisplayName() {
316
return "Color Picker";
320
public Icon getLargeDisplayIcon() {
321
return UIManager.getIcon("ColorChooser.colorPickerIcon");
325
public Icon getSmallDisplayIcon() {
326
return getLargeDisplayIcon();
330
public void updateChooser() {
333
// Variables declaration - do not modify//GEN-BEGIN:variables
334
private javax.swing.JButton pickerButton;
335
// End of variables declaration//GEN-END:variables