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.Component;
30import java.awt.Container;
31import java.awt.GridBagConstraints;
32import java.awt.GridBagLayout;
33import java.beans.PropertyChangeEvent;
34import java.beans.PropertyChangeListener;
35import javax.swing.Icon;
36import javax.swing.JComponent;
37import javax.swing.JFormattedTextField;
38import javax.swing.JLabel;
39import javax.swing.SwingConstants;
40
41@SuppressWarnings("serial") // Superclass is not serializable across versions
42final class ColorChooserPanel extends AbstractColorChooserPanel implements PropertyChangeListener {
43    private static final int MASK = 0xFF000000;
44    private final ColorModel model;
45    private final ColorPanel panel;
46    private final DiagramComponent slider;
47    private final DiagramComponent diagram;
48    private final JFormattedTextField text;
49    private final JLabel label;
50
51    ColorChooserPanel(ColorModel model) {
52        this.model = model;
53        this.panel = new ColorPanel(this.model);
54        this.slider = new DiagramComponent(this.panel, false);
55        this.diagram = new DiagramComponent(this.panel, true);
56        this.text = new JFormattedTextField();
57        this.label = new JLabel(null, null, SwingConstants.RIGHT);
58        ValueFormatter.init(6, true, this.text);
59    }
60
61    @Override
62    public void setEnabled(boolean enabled) {
63        super.setEnabled(enabled);
64        setEnabled(this, enabled);
65    }
66
67    private static void setEnabled(Container container, boolean enabled) {
68        for (Component component : container.getComponents()) {
69            component.setEnabled(enabled);
70            if (component instanceof Container) {
71                setEnabled((Container) component, enabled);
72            }
73        }
74    }
75
76    @Override
77    public void updateChooser() {
78        Color color = getColorFromModel();
79        if (color != null) {
80            this.panel.setColor(color);
81            this.text.setValue(Integer.valueOf(color.getRGB()));
82            this.slider.repaint();
83            this.diagram.repaint();
84        }
85    }
86
87    @Override
88    protected void buildChooser() {
89        if (0 == getComponentCount()) {
90            setLayout(new GridBagLayout());
91
92            GridBagConstraints gbc = new GridBagConstraints();
93
94            gbc.gridx = 3;
95            gbc.gridwidth = 2;
96            gbc.weighty = 1.0;
97            gbc.anchor = GridBagConstraints.NORTH;
98            gbc.fill = GridBagConstraints.HORIZONTAL;
99            gbc.insets.top = 10;
100            gbc.insets.right = 10;
101            add(this.panel, gbc);
102
103            gbc.gridwidth = 1;
104            gbc.weightx = 1.0;
105            gbc.weighty = 0.0;
106            gbc.anchor = GridBagConstraints.CENTER;
107            gbc.insets.right = 5;
108            gbc.insets.bottom = 10;
109            add(this.label, gbc);
110
111            gbc.gridx = 4;
112            gbc.weightx = 0.0;
113            gbc.insets.right = 10;
114            add(this.text, gbc);
115
116            gbc.gridx = 2;
117            gbc.gridheight = 2;
118            gbc.anchor = GridBagConstraints.NORTH;
119            gbc.ipadx = this.text.getPreferredSize().height;
120            gbc.ipady = getPreferredSize().height;
121            add(this.slider, gbc);
122
123            gbc.gridx = 1;
124            gbc.insets.left = 10;
125            gbc.ipadx = gbc.ipady;
126            add(this.diagram, gbc);
127
128            this.label.setLabelFor(this.text);
129            this.text.addPropertyChangeListener("value", this); // NON-NLS: the property name
130            this.slider.setBorder(this.text.getBorder());
131            this.diagram.setBorder(this.text.getBorder());
132
133            setInheritsPopupMenu(this, true); // CR:4966112
134        }
135        String label = this.model.getText(this, "HexCode"); // NON-NLS: suffix
136        boolean visible = label != null;
137        this.text.setVisible(visible);
138        this.text.getAccessibleContext().setAccessibleDescription(label);
139        this.label.setVisible(visible);
140        if (visible) {
141            this.label.setText(label);
142            int mnemonic = this.model.getInteger(this, "HexCodeMnemonic"); // NON-NLS: suffix
143            if (mnemonic > 0) {
144                this.label.setDisplayedMnemonic(mnemonic);
145                mnemonic = this.model.getInteger(this, "HexCodeMnemonicIndex"); // NON-NLS: suffix
146                if (mnemonic >= 0) {
147                    this.label.setDisplayedMnemonicIndex(mnemonic);
148                }
149            }
150        }
151        this.panel.buildPanel();
152    }
153
154    @Override
155    public String getDisplayName() {
156        return this.model.getText(this, "Name"); // NON-NLS: suffix
157    }
158
159    @Override
160    public int getMnemonic() {
161        return this.model.getInteger(this, "Mnemonic"); // NON-NLS: suffix
162    }
163
164    @Override
165    public int getDisplayedMnemonicIndex() {
166        return this.model.getInteger(this, "DisplayedMnemonicIndex"); // NON-NLS: suffix
167    }
168
169    @Override
170    public Icon getSmallDisplayIcon() {
171        return null;
172    }
173
174    @Override
175    public Icon getLargeDisplayIcon() {
176        return null;
177    }
178
179    @Override
180    public void setColorTransparencySelectionEnabled(boolean b){
181        boolean oldValue = isColorTransparencySelectionEnabled();
182        if (b != oldValue) {
183            panel.setColorTransparencySelectionEnabled(b);
184            firePropertyChange(TRANSPARENCY_ENABLED_PROPERTY,
185                    oldValue, b);
186        }
187    }
188
189    @Override
190    public boolean isColorTransparencySelectionEnabled(){
191        return panel.isColorTransparencySelectionEnabled();
192    }
193
194    public void propertyChange(PropertyChangeEvent event) {
195        ColorSelectionModel model = getColorSelectionModel();
196        if (model != null) {
197            Object object = event.getNewValue();
198            if (object instanceof Integer) {
199                int value = MASK & model.getSelectedColor().getRGB() | (Integer) object;
200                model.setSelectedColor(new Color(value, true));
201            }
202        }
203        this.text.selectAll();
204    }
205
206    /**
207     * Allows to show context popup for all components recursively.
208     *
209     * @param component  the root component of the tree
210     * @param value      whether or not the popup menu is inherited
211     */
212    private static void setInheritsPopupMenu(JComponent component, boolean value) {
213        component.setInheritsPopupMenu(value);
214        for (Object object : component.getComponents()) {
215            if (object instanceof JComponent) {
216                setInheritsPopupMenu((JComponent) object, value);
217            }
218        }
219    }
220}
221