2
* Copyright (c) 2005-2010 Substance Kirill Grouchnikov. All Rights Reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
7
* o Redistributions of source code must retain the above copyright notice,
8
* this list of conditions and the following disclaimer.
10
* o Redistributions in binary form must reproduce the above copyright notice,
11
* this list of conditions and the following disclaimer in the documentation
12
* and/or other materials provided with the distribution.
14
* o Neither the name of Substance Kirill Grouchnikov nor the names of
15
* its contributors may be used to endorse or promote products derived
16
* from this software without specific prior written permission.
18
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
import java.awt.datatransfer.*;
34
import java.awt.event.*;
35
import java.awt.image.BufferedImage;
39
import javax.imageio.ImageIO;
42
import org.pushingpixels.lafwidget.utils.RenderingUtils;
43
import org.pushingpixels.substance.internal.utils.border.SubstanceBorder;
45
public class JImageComponent extends JPanel {
46
private BufferedImage image;
54
private boolean isDragging;
56
private Point lastDragPoint;
58
private Color selectedColor;
60
private Color rolloverColor;
62
private File originalFile;
64
private String[] legend;
66
public JImageComponent(boolean hasKeyboardZoom) {
67
this.setTransferHandler(new TransferHandler() {
69
public boolean canImport(TransferSupport support) {
70
// can import a list of files
72
.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
75
if (support.isDataFlavorSupported(DataFlavor.imageFlavor))
77
for (DataFlavor df : support.getDataFlavors()) {
78
// and a flavor represented by URL
79
if (df.getRepresentationClass() == URL.class)
86
public boolean importData(TransferSupport support) {
87
Transferable t = support.getTransferable();
90
if (t.isDataFlavorSupported(DataFlavor.imageFlavor)) {
92
Image data = (Image) t
93
.getTransferData(DataFlavor.imageFlavor);
95
BufferedImage old = image;
96
image = new BufferedImage(data.getWidth(null), data
97
.getHeight(null), BufferedImage.TYPE_INT_ARGB);
98
image.getGraphics().drawImage(data, 0, 0, null);
102
firePropertyChange("image", old, image);
107
if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
108
// load the image from the file
109
java.util.List<File> l = (java.util.List<File>) t
110
.getTransferData(DataFlavor.javaFileListFlavor);
113
BufferedImage oldImage = image;
114
File oldFile = originalFile;
115
originalFile = l.get(0);
116
image = ImageIO.read(originalFile);
120
firePropertyChange("image", oldImage, image);
121
firePropertyChange("file", oldFile, originalFile);
126
for (DataFlavor df : support.getDataFlavors()) {
127
if (df.getRepresentationClass() == URL.class) {
128
// load the image from the URL
129
URL url = (URL) t.getTransferData(df);
131
Image data = ImageIO.read(url);
133
BufferedImage old = image;
134
image = new BufferedImage(data.getWidth(null),
135
data.getHeight(null),
136
BufferedImage.TYPE_INT_ARGB);
137
image.getGraphics().drawImage(data, 0, 0, null);
141
firePropertyChange("image", old, image);
147
} catch (Throwable thr) {
148
thr.printStackTrace();
154
this.addMouseListener(new MouseAdapter() {
156
public void mousePressed(MouseEvent e) {
160
if (!e.isPopupTrigger()) {
161
lastDragPoint = e.getPoint();
168
public void mouseReleased(MouseEvent e) {
169
if (e.isPopupTrigger()) {
178
int xAbs = (int) ((xRel / zoom) + leftX);
179
int yAbs = (int) ((yRel / zoom) + topY);
181
if ((xAbs >= 0) && (xAbs < image.getWidth())
182
&& (yAbs >= 0) && (yAbs < image.getHeight())) {
183
selectedColor = new Color(image.getRGB(xAbs, yAbs));
184
firePropertyChange("selectedColor", null,
192
private void processPopup(MouseEvent e) {
193
JPopupMenu editMenu = new JPopupMenu();
194
editMenu.add(new AbstractAction("paste from clipboard") {
196
public void actionPerformed(ActionEvent e) {
198
Clipboard clipboard = Toolkit.getDefaultToolkit()
199
.getSystemClipboard();
200
DataFlavor[] flavors = clipboard
201
.getAvailableDataFlavors();
202
if (flavors != null) {
203
for (DataFlavor flavor : flavors) {
204
if (Image.class == flavor
205
.getRepresentationClass()) {
206
Image data = (Image) clipboard
209
BufferedImage old = image;
211
image = new BufferedImage(data
212
.getWidth(null), data
214
BufferedImage.TYPE_INT_ARGB);
215
image.getGraphics().drawImage(data, 0,
219
firePropertyChange("image", old, image);
225
} catch (Throwable ignored) {
230
public boolean isEnabled() {
231
Clipboard clipboard = Toolkit.getDefaultToolkit()
232
.getSystemClipboard();
233
DataFlavor[] flavors = clipboard
234
.getAvailableDataFlavors();
235
if (flavors != null) {
236
for (DataFlavor flavor : flavors) {
237
if (Image.class == flavor
238
.getRepresentationClass()) {
246
Point pt = SwingUtilities.convertPoint(e.getComponent(), e
247
.getPoint(), JImageComponent.this);
248
editMenu.show(JImageComponent.this, pt.x, pt.y);
253
this.addMouseMotionListener(new MouseMotionAdapter() {
255
public void mouseDragged(MouseEvent e) {
261
Point currDragPoint = e.getPoint();
262
double dx = ((currDragPoint.x - lastDragPoint.x) / zoom);
263
double dy = ((currDragPoint.y - lastDragPoint.y) / zoom);
267
lastDragPoint = currDragPoint;
272
public void mouseMoved(MouseEvent e) {
278
int xAbs = (int) ((xRel / zoom) + leftX);
279
int yAbs = (int) ((yRel / zoom) + topY);
281
// System.out.println(xRel + ":" + yRel + "->" + xAbs + ":"
284
if ((xAbs >= 0) && (xAbs < image.getWidth()) && (yAbs >= 0)
285
&& (yAbs < image.getHeight())) {
286
Color old = rolloverColor;
287
rolloverColor = new Color(image.getRGB(xAbs, yAbs));
288
firePropertyChange("rolloverColor", old, rolloverColor);
293
this.addMouseWheelListener(new MouseWheelListener() {
295
public void mouseWheelMoved(MouseWheelEvent e) {
296
zoom += e.getScrollAmount() * e.getWheelRotation() / 10.0;
297
zoom = Math.max(1.0, zoom);
302
if (hasKeyboardZoom) {
303
Action zoomInAction = new AbstractAction("zoomin") {
305
public void actionPerformed(ActionEvent e) {
310
Action zoomOutAction = new AbstractAction("zoomout") {
312
public void actionPerformed(ActionEvent e) {
314
zoom = Math.max(1.0, zoom);
319
// create the key input maps to handle the zooming
321
InputMap inputMap = new ComponentInputMap(this);
322
inputMap.put(KeyStroke.getKeyStroke("I"), "zoomin");
323
inputMap.put(KeyStroke.getKeyStroke("O"), "zoomout");
325
ActionMap actionMap = new ActionMap();
326
actionMap.put("zoomin", zoomInAction);
327
actionMap.put("zoomout", zoomOutAction);
329
// and register the maps
330
this.setInputMap(WHEN_IN_FOCUSED_WINDOW, inputMap);
331
this.setActionMap(actionMap);
334
this.setBorder(new SubstanceBorder());
339
public void setLegend(String[] legend) {
340
this.legend = legend;
344
protected void paintComponent(Graphics g) {
345
Graphics2D g2d = (Graphics2D) g.create();
346
g2d.setColor(Color.white);
347
g2d.fillRect(0, 0, getWidth(), getHeight());
349
if (this.image != null) {
350
// zoom from the visible top-left pixel
351
g2d.scale(zoom, zoom);
352
g2d.translate(-this.leftX, -this.topY);
353
g2d.drawImage(this.image, 0, 0, null);
355
RenderingUtils.installDesktopHints(g2d, this);
356
g2d.setFont(UIManager.getFont("Label.font"));
357
g2d.setColor(Color.black);
359
int fh = g2d.getFontMetrics().getHeight();
360
if (this.legend != null) {
361
for (int i = 0; i < this.legend.length; i++) {
362
g2d.drawString(this.legend[i], 10, 20 + i * fh);
370
private void reset() {
376
public BufferedImage getImage() {
380
public File getOriginalFile() {
384
public Point toOriginalImageCoords(int x, int y) {
385
int xAbs = (int) ((x / zoom) + leftX);
386
int yAbs = (int) ((y / zoom) + topY);
387
return new Point(xAbs, yAbs);
b'\\ No newline at end of file'