001/* 002 * $Id: DefaultsList.java 4047 2011-07-19 18:51:12Z 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 */ 021package org.jdesktop.swingx.plaf; 022 023import java.awt.Color; 024import java.awt.Dimension; 025import java.awt.Font; 026import java.awt.Insets; 027import java.util.ArrayList; 028import java.util.List; 029 030import javax.swing.ActionMap; 031import javax.swing.Icon; 032import javax.swing.InputMap; 033import javax.swing.border.Border; 034import javax.swing.plaf.UIResource; 035 036import org.jdesktop.swingx.painter.Painter; 037//import org.jdesktop.swingx.renderer.StringValue; 038import org.jdesktop.swingx.util.Contract; 039 040/** 041 * A specialty "list" for working with UI defaults. Requires adds to be done 042 * using key/value pairs. The purpose of this list is to enforce additions as 043 * pairs. 044 * 045 * @author Karl George Schaefer 046 */ 047@SuppressWarnings("nls") 048public final class DefaultsList { 049 private List<Object> delegate; 050 051 /** 052 * Creates a {@code DefaultsList}. 053 */ 054 public DefaultsList() { 055 delegate = new ArrayList<Object>(); 056 } 057 058 /** 059 * Adds a key/value pair to the defaults list. This implementation defers to 060 * {@link #add(Object, Object, boolean)} with {@code enableChecking} set to 061 * {@code true}. 062 * 063 * @param key 064 * the key that will be used to query {@code UIDefaults} 065 * @param value 066 * the value associated with the key 067 * @throws NullPointerException 068 * if {@code key} is {@code null} 069 * @throws IllegalArgumentException 070 * if {@code value} is a type that should be a 071 * {@code UIResource} but is not. For instance, passing in a 072 * {@code Border} that is not a {@code UIResource} will 073 * cause an exception. This checking must be enabled. 074 */ 075 public void add(Object key, Object value) { 076 add(key, value, true); 077 } 078 079 /** 080 * Adds a key/value pair to the defaults list. A pair with a {@code null} 081 * value is treated specially. A {@code null}-value pair is never added to 082 * the list and, furthermore, if a key/value pair exists in this list with 083 * the same key as the newly added one, it is removed. 084 * 085 * @param key 086 * the key that will be used to query {@code UIDefaults} 087 * @param value 088 * the value associated with the key 089 * @param enableChecking 090 * if {@code true} then the value is checked to ensure that 091 * it is a {@code UIResource}, if appropriate 092 * @throws NullPointerException 093 * if {@code key} is {@code null} 094 * @throws IllegalArgumentException 095 * if {@code value} is a type that should be a 096 * {@code UIResource} but is not. For instance, passing in a 097 * {@code Border} that is not a {@code UIResource} will 098 * cause an exception. This checking must be enabled. 099 */ 100 public void add(Object key, Object value, boolean enableChecking) { 101 if (enableChecking) { 102 asUIResource(value, value + " must be a UIResource"); 103 } 104 105 if (value == null && delegate.contains(key)) { 106 int i = delegate.indexOf(key); 107 108 delegate.remove(i + 1); 109 delegate.remove(i); 110 } else if (value != null) { 111 delegate.add(Contract.asNotNull(key, "key cannot be null")); 112 delegate.add(value); 113 } 114 } 115 116 //TODO move to Contract? 117 private static <T> T asUIResource(T value, String message) { 118 if (!(value instanceof UIResource)) { 119 boolean shouldThrow = false; 120 121 shouldThrow |= value instanceof ActionMap; 122 shouldThrow |= value instanceof Border; 123 shouldThrow |= value instanceof Color; 124 shouldThrow |= value instanceof Dimension; 125 shouldThrow |= value instanceof Font; 126 shouldThrow |= value instanceof Icon; 127 shouldThrow |= value instanceof InputMap; 128 shouldThrow |= value instanceof Insets; 129 shouldThrow |= value instanceof Painter<?>; 130 //FIXME how to handle UIResource testing 131// shouldThrow |= value instanceof StringValue; 132 133 if (shouldThrow) { 134 throw new IllegalArgumentException(message); 135 } 136 } 137 138 return value; 139 } 140 141 /** 142 * Gets a copy of this list as an array. 143 * 144 * @return an array containing all of the key/value pairs added to this list 145 */ 146 public Object[] toArray() { 147 return delegate.toArray(); 148 } 149}