1/*
2 * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package javax.swing.colorchooser;
27
28import java.awt.Color;
29import java.awt.Graphics;
30import java.awt.Insets;
31import java.awt.event.MouseEvent;
32import java.awt.event.MouseListener;
33import java.awt.event.MouseMotionListener;
34import java.awt.image.BufferedImage;
35import javax.swing.JComponent;
36
37@SuppressWarnings("serial") // Superclass is not serializable across versions
38final class DiagramComponent extends JComponent implements MouseListener, MouseMotionListener {
39
40    private final ColorPanel panel;
41    private final boolean diagram;
42
43    private final Insets insets = new Insets(0, 0, 0, 0);
44
45    private int width;
46    private int height;
47
48    private int[] array;
49    private BufferedImage image;
50
51    DiagramComponent(ColorPanel panel, boolean diagram) {
52        this.panel = panel;
53        this.diagram = diagram;
54        addMouseListener(this);
55        addMouseMotionListener(this);
56    }
57
58    @Override
59    protected void paintComponent(Graphics g) {
60        getInsets(this.insets);
61        this.width = getWidth() - this.insets.left - this.insets.right;
62        this.height = getHeight() - this.insets.top - this.insets.bottom;
63        if ((this.width <= 0) || (this.height <= 0))
64            return;
65        boolean update = (this.image == null)
66                || (this.width != this.image.getWidth())
67                || (this.height != this.image.getHeight());
68        if (update) {
69            int size = this.width * this.height;
70            if ((this.array == null) || (this.array.length < size)) {
71                this.array = new int[size];
72            }
73            this.image = new BufferedImage(this.width, this.height, BufferedImage.TYPE_INT_RGB);
74        }
75        {
76            float dx = 1.0f / (float) (this.width - 1);
77            float dy = 1.0f / (float) (this.height - 1);
78
79            int offset = 0;
80            float y = 0.0f;
81            for (int h = 0; h < this.height; h++, y += dy) {
82                if (this.diagram) {
83                    float x = 0.0f;
84                    for (int w = 0; w < this.width; w++, x += dx, offset++) {
85                        this.array[offset] = this.panel.getColor(x, y);
86                    }
87                }
88                else {
89                    int color = this.panel.getColor(y);
90                    for (int w = 0; w < this.width; w++, offset++) {
91                        this.array[offset] = color;
92                    }
93                }
94            }
95        }
96        this.image.setRGB(0, 0, this.width, this.height, this.array, 0, this.width);
97        g.drawImage(this.image, this.insets.left, this.insets.top, this.width, this.height, this);
98        if (isEnabled()) {
99            this.width--;
100            this.height--;
101            g.setXORMode(Color.WHITE);
102            g.setColor(Color.BLACK);
103            if (this.diagram) {
104                int x = getValue(this.panel.getValueX(), this.insets.left, this.width);
105                int y = getValue(this.panel.getValueY(), this.insets.top, this.height);
106                g.drawLine(x - 8, y, x + 8, y);
107                g.drawLine(x, y - 8, x, y + 8);
108            }
109            else {
110                int z = getValue(this.panel.getValueZ(), this.insets.top, this.height);
111                g.drawLine(this.insets.left, z, this.insets.left + this.width, z);
112            }
113            g.setPaintMode();
114        }
115    }
116
117    public void mousePressed(MouseEvent event) {
118        mouseDragged(event);
119    }
120
121    public void mouseReleased(MouseEvent event) {
122    }
123
124    public void mouseClicked(MouseEvent event) {
125    }
126
127    public void mouseEntered(MouseEvent event) {
128    }
129
130    public void mouseExited(MouseEvent event) {
131    }
132
133    public void mouseMoved(MouseEvent event) {
134    }
135
136    public void mouseDragged(MouseEvent event) {
137        if (isEnabled()) {
138            float y = getValue(event.getY(), this.insets.top, this.height);
139            if (this.diagram) {
140                float x = getValue(event.getX(), this.insets.left, this.width);
141                this.panel.setValue(x, y);
142            }
143            else {
144                this.panel.setValue(y);
145            }
146        }
147    }
148
149    private static int getValue(float value, int min, int max) {
150        return min + (int) (value * (float) (max));
151    }
152
153    private static float getValue(int value, int min, int max) {
154        if (min < value) {
155            value -= min;
156            return (value < max)
157                    ? (float) value / (float) max
158                    : 1.0f;
159        }
160        return 0.0f;
161    }
162}
163