1 /*
2 * Copyright 1997-2008 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package javax.swing.plaf.basic;
27
28 import javax.swing;
29 import javax.swing.colorchooser;
30 import javax.swing.event;
31 import javax.swing.border;
32 import javax.swing.plaf;
33 import java.awt;
34 import java.awt.event;
35 import java.beans.PropertyChangeEvent;
36 import java.beans.PropertyChangeListener;
37
38 import sun.swing.DefaultLookup;
39
40 /**
41 * Provides the basic look and feel for a JColorChooser.
42 * <p>
43 * @author Tom Santos
44 * @author Steve Wilson
45 */
46
47 public class BasicColorChooserUI extends ColorChooserUI
48 {
49 /**
50 * JColorChooser this BasicColorChooserUI is installed on.
51 *
52 * @since 1.5
53 */
54 protected JColorChooser chooser;
55
56 JTabbedPane tabbedPane;
57 JPanel singlePanel;
58
59 JPanel previewPanelHolder;
60 JComponent previewPanel;
61 boolean isMultiPanel = false;
62 private static TransferHandler defaultTransferHandler = new ColorTransferHandler();
63
64 protected AbstractColorChooserPanel[] defaultChoosers;
65
66 protected ChangeListener previewListener;
67 protected PropertyChangeListener propertyChangeListener;
68 private Handler handler;
69
70 public static ComponentUI createUI(JComponent c) {
71 return new BasicColorChooserUI();
72 }
73
74 protected AbstractColorChooserPanel[] createDefaultChoosers() {
75 AbstractColorChooserPanel[] panels = ColorChooserComponentFactory.getDefaultChooserPanels();
76 return panels;
77 }
78
79 protected void uninstallDefaultChoosers() {
80 AbstractColorChooserPanel[] choosers = chooser.getChooserPanels();
81 for( int i = 0 ; i < choosers.length; i++) {
82 chooser.removeChooserPanel( choosers[i] );
83 }
84 }
85
86 public void installUI( JComponent c ) {
87 chooser = (JColorChooser)c;
88
89 super.installUI( c );
90
91 installDefaults();
92 installListeners();
93
94 tabbedPane = new JTabbedPane();
95 tabbedPane.setName("ColorChooser.tabPane");
96 tabbedPane.setInheritsPopupMenu(true);
97 singlePanel = new JPanel(new CenterLayout());
98 singlePanel.setName("ColorChooser.panel");
99 singlePanel.setInheritsPopupMenu(true);
100
101 chooser.setLayout( new BorderLayout() );
102
103 defaultChoosers = createDefaultChoosers();
104 chooser.setChooserPanels(defaultChoosers);
105
106 previewPanelHolder = new JPanel(new CenterLayout());
107 previewPanelHolder.setName("ColorChooser.previewPanelHolder");
108
109 if (DefaultLookup.getBoolean(chooser, this,
110 "ColorChooser.showPreviewPanelText", true)) {
111 String previewString = UIManager.getString(
112 "ColorChooser.previewText", chooser.getLocale());
113 previewPanelHolder.setBorder(new TitledBorder(previewString));
114 }
115 previewPanelHolder.setInheritsPopupMenu(true);
116 chooser.add(previewPanelHolder, BorderLayout.SOUTH);
117
118 installPreviewPanel();
119 chooser.applyComponentOrientation(c.getComponentOrientation());
120 }
121
122 public void uninstallUI( JComponent c ) {
123 chooser.remove(tabbedPane);
124 chooser.remove(singlePanel);
125 chooser.remove(previewPanelHolder);
126
127 uninstallDefaultChoosers();
128 uninstallListeners();
129 uninstallDefaults();
130
131 previewPanelHolder.remove(previewPanel);
132 if (previewPanel instanceof UIResource) {
133 chooser.setPreviewPanel(null);
134 }
135
136 previewPanelHolder = null;
137 previewPanel = null;
138 defaultChoosers = null;
139 chooser = null;
140 tabbedPane = null;
141
142 handler = null;
143 }
144
145 protected void installPreviewPanel() {
146 if (previewPanel != null) {
147 previewPanelHolder.remove(previewPanel);
148 previewPanel.removeMouseListener(getHandler());
149 }
150
151 previewPanel = chooser.getPreviewPanel();
152 Dimension layoutSize = new Dimension(); // fix for bug 4759306
153 if (previewPanel != null) {
154 layoutSize = new BorderLayout().minimumLayoutSize(previewPanel);
155 if ((previewPanelHolder != null) && (chooser != null) &&
156 (layoutSize.getWidth() + layoutSize.getHeight() == 0)) {
157 chooser.remove(previewPanelHolder);
158 return;
159 }
160 }
161 if (previewPanel == null || previewPanel instanceof UIResource) {
162 previewPanel = ColorChooserComponentFactory.getPreviewPanel(); // get from table?
163 chooser.setPreviewPanel(previewPanel);
164 }
165 previewPanel.setForeground(chooser.getColor());
166 previewPanelHolder.add(previewPanel);
167 previewPanel.addMouseListener(getHandler());
168 previewPanel.setInheritsPopupMenu(true);
169 }
170
171 protected void installDefaults() {
172 LookAndFeel.installColorsAndFont(chooser, "ColorChooser.background",
173 "ColorChooser.foreground",
174 "ColorChooser.font");
175 LookAndFeel.installProperty(chooser, "opaque", Boolean.TRUE);
176 TransferHandler th = chooser.getTransferHandler();
177 if (th == null || th instanceof UIResource) {
178 chooser.setTransferHandler(defaultTransferHandler);
179 }
180 }
181
182 protected void uninstallDefaults() {
183 if (chooser.getTransferHandler() instanceof UIResource) {
184 chooser.setTransferHandler(null);
185 }
186 }
187
188
189 protected void installListeners() {
190 propertyChangeListener = createPropertyChangeListener();
191 chooser.addPropertyChangeListener( propertyChangeListener );
192
193 previewListener = getHandler();
194 chooser.getSelectionModel().addChangeListener(previewListener);
195 }
196
197 private Handler getHandler() {
198 if (handler == null) {
199 handler = new Handler();
200 }
201 return handler;
202 }
203
204 protected PropertyChangeListener createPropertyChangeListener() {
205 return getHandler();
206 }
207
208 protected void uninstallListeners() {
209 chooser.removePropertyChangeListener( propertyChangeListener );
210 chooser.getSelectionModel().removeChangeListener(previewListener);
211 previewListener = null;
212 previewPanel.removeMouseListener(getHandler());
213 }
214
215 private void selectionChanged(ColorSelectionModel model) {
216 if (this.previewPanel != null) {
217 this.previewPanel.setForeground(model.getSelectedColor());
218 this.previewPanel.repaint();
219 }
220 AbstractColorChooserPanel[] panels = this.chooser.getChooserPanels();
221 if (panels != null) {
222 for (AbstractColorChooserPanel panel : panels) {
223 if (panel != null) {
224 panel.updateChooser();
225 }
226 }
227 }
228 }
229
230 private class Handler implements ChangeListener, MouseListener,
231 PropertyChangeListener {
232 //
233 // ChangeListener
234 //
235 public void stateChanged(ChangeEvent evt) {
236 selectionChanged((ColorSelectionModel) evt.getSource());
237 }
238
239 //
240 // MouseListener
241 public void mousePressed(MouseEvent evt) {
242 if (chooser.getDragEnabled()) {
243 TransferHandler th = chooser.getTransferHandler();
244 th.exportAsDrag(chooser, evt, TransferHandler.COPY);
245 }
246 }
247 public void mouseReleased(MouseEvent evt) {}
248 public void mouseClicked(MouseEvent evt) {}
249 public void mouseEntered(MouseEvent evt) {}
250 public void mouseExited(MouseEvent evt) {}
251
252 //
253 // PropertyChangeListener
254 //
255 public void propertyChange(PropertyChangeEvent evt) {
256 String prop = evt.getPropertyName();
257
258 if (prop == JColorChooser.CHOOSER_PANELS_PROPERTY) {
259 AbstractColorChooserPanel[] oldPanels =
260 (AbstractColorChooserPanel[])evt.getOldValue();
261 AbstractColorChooserPanel[] newPanels =
262 (AbstractColorChooserPanel[])evt.getNewValue();
263
264 for (int i = 0; i < oldPanels.length; i++) { // remove old panels
265 Container wrapper = oldPanels[i].getParent();
266 if (wrapper != null) {
267 Container parent = wrapper.getParent();
268 if (parent != null)
269 parent.remove(wrapper); // remove from hierarchy
270 oldPanels[i].uninstallChooserPanel(chooser); // uninstall
271 }
272 }
273
274 int numNewPanels = newPanels.length;
275 if (numNewPanels == 0) { // removed all panels and added none
276 chooser.remove(tabbedPane);
277 return;
278 }
279 else if (numNewPanels == 1) { // one panel case
280 chooser.remove(tabbedPane);
281 JPanel centerWrapper = new JPanel( new CenterLayout() );
282 centerWrapper.setInheritsPopupMenu(true);
283 centerWrapper.add(newPanels[0]);
284 singlePanel.add(centerWrapper, BorderLayout.CENTER);
285 chooser.add(singlePanel);
286 }
287 else { // multi-panel case
288 if ( oldPanels.length < 2 ) {// moving from single to multiple
289 chooser.remove(singlePanel);
290 chooser.add(tabbedPane, BorderLayout.CENTER);
291 }
292
293 for (int i = 0; i < newPanels.length; i++) {
294 JPanel centerWrapper = new JPanel( new CenterLayout() );
295 centerWrapper.setInheritsPopupMenu(true);
296 String name = newPanels[i].getDisplayName();
297 int mnemonic = newPanels[i].getMnemonic();
298 centerWrapper.add(newPanels[i]);
299 tabbedPane.addTab(name, centerWrapper);
300 if (mnemonic > 0) {
301 tabbedPane.setMnemonicAt(i, mnemonic);
302 tabbedPane.setDisplayedMnemonicIndexAt(
303 i, newPanels[i].getDisplayedMnemonicIndex());
304 }
305 }
306 }
307 chooser.applyComponentOrientation(chooser.getComponentOrientation());
308 for (int i = 0; i < newPanels.length; i++) {
309 newPanels[i].installChooserPanel(chooser);
310 }
311 }
312 else if (prop == JColorChooser.PREVIEW_PANEL_PROPERTY) {
313 if (evt.getNewValue() != previewPanel) {
314 installPreviewPanel();
315 }
316 }
317 else if (prop == JColorChooser.SELECTION_MODEL_PROPERTY) {
318 ColorSelectionModel oldModel = (ColorSelectionModel) evt.getOldValue();
319 oldModel.removeChangeListener(previewListener);
320 ColorSelectionModel newModel = (ColorSelectionModel) evt.getNewValue();
321 newModel.addChangeListener(previewListener);
322 selectionChanged(newModel);
323 }
324 else if (prop == "componentOrientation") {
325 ComponentOrientation o =
326 (ComponentOrientation)evt.getNewValue();
327 JColorChooser cc = (JColorChooser)evt.getSource();
328 if (o != (ComponentOrientation)evt.getOldValue()) {
329 cc.applyComponentOrientation(o);
330 cc.updateUI();
331 }
332 }
333 }
334 }
335
336 /**
337 * This inner class is marked "public" due to a compiler bug.
338 * This class should be treated as a "protected" inner class.
339 * Instantiate it only within subclasses of <Foo>.
340 */
341 public class PropertyHandler implements PropertyChangeListener {
342 public void propertyChange(PropertyChangeEvent e) {
343 getHandler().propertyChange(e);
344 }
345 }
346
347 static class ColorTransferHandler extends TransferHandler implements UIResource {
348
349 ColorTransferHandler() {
350 super("color");
351 }
352 }
353
354 }