001 /*
002 * $Id: DefaultsList.java 2668 2008-02-06 04:19:28Z kschaefe $
003 *
004 * Copyright 2007 Sun Microsystems, Inc., 4150 Network Circle,
005 * Santa Clara, California 95054, U.S.A. All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020 */
021 package org.jdesktop.swingx.plaf;
022
023 import java.awt.Color;
024 import java.awt.Dimension;
025 import java.awt.Font;
026 import java.awt.Insets;
027 import java.util.ArrayList;
028 import java.util.List;
029
030 import javax.swing.ActionMap;
031 import javax.swing.Icon;
032 import javax.swing.InputMap;
033 import javax.swing.border.Border;
034 import javax.swing.plaf.UIResource;
035
036 import org.jdesktop.swingx.painter.Painter;
037 import org.jdesktop.swingx.util.Contract;
038
039 /**
040 * A specialty "list" for working with UI defaults. Requires adds to be done
041 * using key/value pairs. The purpose of this list is to enforce additions as
042 * pairs.
043 *
044 * @author Karl George Schaefer
045 */
046 public final class DefaultsList {
047 private List<Object> delegate;
048
049 /**
050 * Creates a {@code DefaultsList}.
051 */
052 public DefaultsList() {
053 delegate = new ArrayList<Object>();
054 }
055
056 /**
057 * Adds a key/value pair to the defaults list. This implementation defers to
058 * {@link #add(Object, Object, boolean)} with {@code enableChecking} set to
059 * {@code true}.
060 *
061 * @param key
062 * the key that will be used to query {@code UIDefaults}
063 * @param value
064 * the value associated with the key
065 * @throws NullPointerException
066 * if {@code key} is {@code null}
067 * @throws IllegalArgumentException
068 * if {@code value} is a type that should be a
069 * {@code UIResource} but is not. For instance, passing in a
070 * {@code Border} that is not a {@code UIResource} will
071 * cause an exception. This checking must be enabled.
072 */
073 public void add(Object key, Object value) {
074 add(key, value, true);
075 }
076
077 /**
078 * Adds a key/value pair to the defaults list. A pair with a {@code null}
079 * value is treated specially. A {@code null}-value pair is never added to
080 * the list and, furthermore, if a key/value pair exists in this list with
081 * the same key as the newly added one, it is removed.
082 *
083 * @param key
084 * the key that will be used to query {@code UIDefaults}
085 * @param value
086 * the value associated with the key
087 * @param enableChecking
088 * if {@code true} then the value is checked to ensure that
089 * it is a {@code UIResource}, if appropriate
090 * @throws NullPointerException
091 * if {@code key} is {@code null}
092 * @throws IllegalArgumentException
093 * if {@code value} is a type that should be a
094 * {@code UIResource} but is not. For instance, passing in a
095 * {@code Border} that is not a {@code UIResource} will
096 * cause an exception. This checking must be enabled.
097 */
098 public void add(Object key, Object value, boolean enableChecking) {
099 if (enableChecking) {
100 asUIResource(value, value + " must be a UIResource");
101 }
102
103 if (value == null && delegate.contains(key)) {
104 int i = delegate.indexOf(key);
105
106 delegate.remove(i + 1);
107 delegate.remove(i);
108 } else if (value != null) {
109 delegate.add(Contract.asNotNull(key, "key cannot be null"));
110 delegate.add(value);
111 }
112 }
113
114 //TODO move to Contract?
115 private static <T> T asUIResource(T value, String message) {
116 if (!(value instanceof UIResource)) {
117 boolean shouldThrow = false;
118
119 shouldThrow |= value instanceof ActionMap;
120 shouldThrow |= value instanceof Border;
121 shouldThrow |= value instanceof Color;
122 shouldThrow |= value instanceof Dimension;
123 shouldThrow |= value instanceof Font;
124 shouldThrow |= value instanceof Icon;
125 shouldThrow |= value instanceof InputMap;
126 shouldThrow |= value instanceof Insets;
127 shouldThrow |= value instanceof Painter;
128
129 if (shouldThrow) {
130 throw new IllegalArgumentException(message);
131 }
132 }
133
134 return value;
135 }
136
137 /**
138 * Gets a copy of this list as an array.
139 *
140 * @return an array containing all of the key/value pairs added to this list
141 */
142 public Object[] toArray() {
143 return delegate.toArray();
144 }
145 }