2
* @(#)Quaqua15ColorPicker.java 1.2 2006-04-23
4
* Copyright (c) 2005-2006 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;
31
* Quaqua15ColorPicker.
35
* @author Werner Randelshofer
36
* @version 1.2 2006-04-23 Retrieve labels from UIManager. <br>
37
* 1.1.1 2006-03-15 Forgot to create robot instance. <br>
38
* 1.1 2006-03-06 Abort picker when the user presses the Escape-Key. <br>
39
* 1.0 December 18, 2005 Created.
41
public class Quaqua15ColorPicker extends AbstractColorChooserPanel {
43
* This frame is constantly moved to the current location of the mouse. This
44
* ensures that we can trap mouse clicks while the picker cursor is showing.
45
* Also, by tying the picker cursor to this frame, we ensure that the picker
46
* cursor (the magnifying glass) is shown.
48
private Dialog pickerFrame;
50
private Timer pickerTimer;
53
* Holds the image of the picker cursor.
55
private BufferedImage cursorImage;
57
* Graphics object used for drawing on the cursorImage.
59
private Graphics2D cursorGraphics;
64
private Cursor pickerCursor;
67
* The hot spot of the cursor.
69
private Point hotSpot;
72
* Offset from the hot spot of the pickerCursor to the pixel that we want to
73
* pick. We can't pick the color at the hotSpot of the cursor, because this
74
* point is obscured by the pickerFrame.
76
private Point pickOffset;
79
* The magnifying glass image.
81
private BufferedImage magnifierImage;
84
* The robot is used for creating screen captures.
88
private Color previousColor = Color.white;
89
private Point previousLoc = new Point();
90
private Point pickLoc = new Point();
91
private Point captureOffset = new Point();
92
private Rectangle captureRect;
93
private final static Color transparentColor = new Color(0, true);
94
private Rectangle zoomRect;
95
private Rectangle glassRect;
98
* Creates a new instance.
100
public Quaqua15ColorPicker() {
101
// Try immediately to create a screen capture in order to fail quickly,
103
// we can't provide a color picker functionality.
106
robot.createScreenCapture(new Rectangle(0, 0, 1, 1));
107
} catch (AWTException e) {
108
throw new AccessControlException("Unable to capture screen");
114
* Gets the picker frame. If the frame does not yet exist, it is created
115
* along with all the other objects that are needed to make the picker work.
117
private Dialog getPickerFrame() {
118
if (pickerFrame == null) {
119
Window owner = SwingUtilities.getWindowAncestor(this);
120
if (owner instanceof Dialog) {
121
pickerFrame = new Dialog((Dialog) owner);
122
} else if (owner instanceof Frame) {
123
pickerFrame = new Dialog((Frame) owner);
125
pickerFrame = new Dialog(new JFrame());
128
pickerFrame.addMouseListener(new MouseAdapter() {
130
public void mousePressed(MouseEvent evt) {
135
public void mouseExited(MouseEvent evt) {
140
pickerFrame.addMouseMotionListener(new MouseMotionAdapter() {
142
public void mouseMoved(MouseEvent evt) {
146
pickerFrame.setSize(3, 3);
147
pickerFrame.setUndecorated(true);
148
pickerFrame.setAlwaysOnTop(true);
150
pickerFrame.addKeyListener(new KeyAdapter() {
152
public void keyPressed(KeyEvent e) {
153
switch (e.getKeyCode()) {
154
case KeyEvent.VK_ESCAPE:
157
case KeyEvent.VK_ENTER:
164
magnifierImage = (BufferedImage) UIManager
165
.get("ColorChooser.colorPickerMagnifier");
166
glassRect = (Rectangle) UIManager
167
.get("ColorChooser.colorPickerGlassRect");
168
zoomRect = (Rectangle) UIManager
169
.get("ColorChooser.colorPickerZoomRect");
170
hotSpot = (Point) UIManager.get("ColorChooser.colorPickerHotSpot");// new
173
captureRect = new Rectangle((Rectangle) UIManager
174
.get("ColorChooser.colorPickerCaptureRect"));
175
pickOffset = (Point) UIManager
176
.get("ColorChooser.colorPickerPickOffset");
177
captureOffset = new Point(captureRect.x, captureRect.y);
178
cursorImage = getGraphicsConfiguration().createCompatibleImage(
179
magnifierImage.getWidth(), magnifierImage.getHeight(),
180
Transparency.TRANSLUCENT);
181
cursorGraphics = cursorImage.createGraphics();
182
cursorGraphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
183
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
185
pickerTimer = new Timer(5, new ActionListener() {
187
public void actionPerformed(ActionEvent evt) {
196
* Updates the color picker.
198
protected void updatePicker() {
199
if (pickerFrame != null && pickerFrame.isShowing()) {
200
PointerInfo info = MouseInfo.getPointerInfo();
201
if (info == null) return; //pointer not on a graphics device
202
Point mouseLoc = info.getLocation();
203
pickerFrame.setLocation(mouseLoc.x - pickerFrame.getWidth() / 2,
204
mouseLoc.y - pickerFrame.getHeight() / 2);
206
pickLoc.x = mouseLoc.x + pickOffset.x;
207
pickLoc.y = mouseLoc.y + pickOffset.y;
209
if (pickLoc.x >= 0 && pickLoc.y >= 0) {
210
Color c = robot.getPixelColor(pickLoc.x, pickLoc.y);
211
if (!c.equals(previousColor) || !mouseLoc.equals(previousLoc)) {
213
previousLoc = mouseLoc;
215
captureRect.setLocation(mouseLoc.x + captureOffset.x,
216
mouseLoc.y + captureOffset.y);
217
if (captureRect.x >= 0 && captureRect.y >= 0) {
218
BufferedImage capture = robot
219
.createScreenCapture(captureRect);
221
// Clear the cursor graphics
222
cursorGraphics.setComposite(AlphaComposite.Src);
223
cursorGraphics.setColor(transparentColor);
224
cursorGraphics.fillRect(0, 0, cursorImage.getWidth(),
225
cursorImage.getHeight());
227
// Fill the area for the zoomed screen capture with a
228
// non-transparent color (any non-transparent color does
230
cursorGraphics.setColor(Color.red);
231
cursorGraphics.fillOval(glassRect.x, glassRect.y,
232
glassRect.width, glassRect.height);
234
// Paint the screen capture with a zoom factor of 5
235
cursorGraphics.setComposite(AlphaComposite.SrcIn);
236
cursorGraphics.drawImage(capture, zoomRect.x,
237
zoomRect.y, zoomRect.width, zoomRect.height,
240
// Draw the magnifying glass image
241
cursorGraphics.setComposite(AlphaComposite.SrcOver);
242
cursorGraphics.drawImage(magnifierImage, 0, 0, this);
244
// We need to create a new subImage. This forces that
245
// the color picker uses the new imagery.
246
BufferedImage subImage = cursorImage
247
.getSubimage(0, 0, cursorImage.getWidth(),
248
cursorImage.getHeight());
249
pickerFrame.setCursor(getToolkit().createCustomCursor(
250
cursorImage, hotSpot, "ColorPicker"));
258
* This method is called from within the constructor to initialize the form.
259
* WARNING: Do NOT modify this code. The content of this method is always
260
* regenerated by the Form Editor.
262
private void initComponents() {// GEN-BEGIN:initComponents
263
pickerButton = new javax.swing.JButton();
265
setLayout(new java.awt.BorderLayout());
267
// pickerButton.setBorderPainted(false);
268
pickerButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
269
pickerButton.addActionListener(new java.awt.event.ActionListener() {
271
public void actionPerformed(java.awt.event.ActionEvent evt) {
276
add(pickerButton, java.awt.BorderLayout.CENTER);
278
}// GEN-END:initComponents
280
private void pickBegin(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_pickBegin
283
getPickerFrame().setVisible(true);
284
}// GEN-LAST:event_pickBegin
286
protected void pickFinish() {
288
pickerFrame.setVisible(false);
289
PointerInfo info = MouseInfo.getPointerInfo();
290
if (info == null) return; //pointer not on a graphics device
291
Point loc = info.getLocation();
292
Color c = robot.getPixelColor(loc.x + pickOffset.x, loc.y
294
getColorSelectionModel().setSelectedColor(c);
297
protected void pickCancel() {
299
pickerFrame.setVisible(false);
303
protected void buildChooser() {
305
pickerButton.setIcon(new TransitionAwareIcon(pickerButton,
306
new TransitionAwareIcon.Delegate() {
308
public Icon getColorSchemeIcon(SubstanceColorScheme scheme) {
309
return new IconUIResource(SubstanceImageCreator
310
.getSearchIcon(15, scheme, pickerButton
311
.getComponentOrientation()
314
}, "ColorChooser.colorPickerIcon"));
318
public String getDisplayName() {
319
return UIManager.getString("ColorChooser.colorPicker");
323
public Icon getLargeDisplayIcon() {
324
return UIManager.getIcon("ColorChooser.colorPickerIcon");
328
public Icon getSmallDisplayIcon() {
329
return getLargeDisplayIcon();
333
public void updateChooser() {
336
// Variables declaration - do not modify//GEN-BEGIN:variables
337
private javax.swing.JButton pickerButton;
338
// End of variables declaration//GEN-END:variables