View Javadoc

1   /*
2    * Copyright (c) 2003-2008 by Cosylab d. d.
3    *
4    * This file is part of CosyBeans-Common.
5    *
6    * CosyBeans-Common is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * CosyBeans-Common is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with CosyBeans-Common.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  package com.cosylab.gui.components.introspection;
21  
22  import com.cosylab.introspection.BeanIntrospector;
23  import com.cosylab.introspection.ClassIntrospector;
24  
25  import java.awt.BorderLayout;
26  
27  import java.beans.IntrospectionException;
28  import java.beans.PropertyChangeEvent;
29  import java.beans.PropertyChangeListener;
30  import java.beans.PropertyDescriptor;
31  
32  import java.lang.reflect.InvocationTargetException;
33  import java.lang.reflect.Method;
34  
35  import javax.swing.JButton;
36  import javax.swing.JFrame;
37  import javax.swing.JPanel;
38  import javax.swing.JScrollPane;
39  import javax.swing.event.TableModelEvent;
40  import javax.swing.event.TableModelListener;
41  
42  
43  /**
44   * This table parforms introspection on Java bean and displays editable table
45   * in which user can change bean properties.
46   *
47   * @author <a href="mailto:miha.kadunc@cosylab.com">Miha Kadunc</a>
48   * @version $id$
49   */
50  public class PropertiesTable extends DefaultPropertiesTable
51  {
52  	private static final long serialVersionUID = 1L;
53  	private String[] propertyNames;
54  	private PropertyDescriptor[] propertyDescriptors;
55  	private Object fieldBean = null;
56  
57  	/**
58  	 * ParametersTable constructor comment.
59  	 */
60  	public PropertiesTable()
61  	{
62  		super();
63  		initialize();
64  	}
65  
66  	/**
67  	 * ParametersTable constructor comment.
68  	 *
69  	 * @param properties DOCUMENT ME!
70  	 */
71  	public PropertiesTable(String[] properties)
72  	{
73  		super();
74  		initialize();
75  		propertyNames = properties;
76  	}
77  	
78  	/**
79  	 * ParametersTable constructor comment.
80  	 *
81  	 * @param properties DOCUMENT ME!
82  	 */
83  	public PropertiesTable(PropertyDescriptor[] properties)
84  	{
85  		super();
86  		initialize();
87  		propertyDescriptors= properties;
88  		propertyNames = BeanIntrospector.getPropertyNames(properties);
89  	}
90  	
91  	
92  
93  	/**
94  	 * Gets the bean property value.
95  	 *
96  	 * @return The bean property value.
97  	 *
98  	 * @see #setMethod
99  	 */
100 	public Object getBean()
101 	{
102 		return fieldBean;
103 	}
104 
105 	/**
106 	 * Initialize the class.
107 	 *
108 	 * @throws RuntimeException DOCUMENT ME!
109 	 */
110 	private void initialize()
111 	{
112 		final PropertiesTableModel parametersModel = (PropertiesTableModel)getModel();
113 		parametersModel.addTableModelListener(new TableModelListener() {
114 				public void tableChanged(TableModelEvent e)
115 				{
116 					if (e.getColumn() == 1) {
117 						try {
118 							String name = parametersModel.getPropertyNames()[e
119 								.getFirstRow()];
120 							Object val = parametersModel.getPropertyValues()[e
121 								.getFirstRow()];
122 
123 							/*firePropertyChange is necessary for NetBeans gui builder*/
124 							firePropertyChange(name, null, val);
125 							BeanIntrospector.setPropertyValue(fieldBean, name,
126 							    val);
127 						} catch (Exception exc) {
128 							throw new RuntimeException("Could not automatically set the property on the bean",
129 							    exc);
130 						}
131 					}
132 				}
133 			});
134 	}
135 
136 	/**
137 	 * main entrypoint - starts the part when it is run as an application
138 	 *
139 	 * @param args java.lang.String[]
140 	 */
141 	public static void main(java.lang.String[] args)
142 	{
143 		try {
144 			JFrame frame = new JFrame();
145 			JPanel panel = new JPanel();
146 			JScrollPane sp = new JScrollPane();
147 			PropertiesTable aParametersTable;
148 			aParametersTable = new PropertiesTable();
149 
150 			sp.add(aParametersTable);
151 			sp.setViewportView(aParametersTable);
152 			panel.setLayout(new BorderLayout());
153 			panel.add(sp, BorderLayout.CENTER);
154 
155 			JButton but = new JButton();
156 			panel.add(but, BorderLayout.NORTH);
157 			frame.setContentPane(panel);
158 			frame.setSize(200, 100);
159 			frame.addWindowListener(new java.awt.event.WindowAdapter() {
160 					public void windowClosing(java.awt.event.WindowEvent e)
161 					{
162 						System.exit(0);
163 					}
164 					;
165 				});
166 			frame.setVisible(true);
167 			aParametersTable.setBean(but);
168 
169 			java.awt.Insets insets = frame.getInsets();
170 			frame.setSize(frame.getWidth() + insets.left + insets.right,
171 			    frame.getHeight() + insets.top + insets.bottom);
172 			frame.setVisible(true);
173 		} catch (Throwable exception) {
174 			System.err.println(
175 			    "Exception occurred in main() of com.cosylab.introspection.ParametersTable");
176 			exception.printStackTrace(System.out);
177 		}
178 	}
179 
180 	/**
181 	 * Sets the method property (java.lang.reflect.Method) value.
182 	 *
183 	 * @param bean The new value for the property.
184 	 *
185 	 * @throws IntrospectionException DOCUMENT ME!
186 	 * @throws IllegalAccessException DOCUMENT ME!
187 	 * @throws InvocationTargetException DOCUMENT ME!
188 	 *
189 	 * @see #getMethod
190 	 */
191 	public void setBean(Object bean)
192 		throws IntrospectionException, IllegalAccessException, 
193 			InvocationTargetException
194 	{
195 
196 		if (propertyNames != null) {
197 			if (propertyDescriptors==null) {
198 				propertyDescriptors = new PropertyDescriptor[propertyNames.length];
199 	
200 				for (int i = 0; i < propertyNames.length; i++) {
201 					propertyDescriptors[i] = BeanIntrospector.getPropertyDescriptor(bean
202 						    .getClass(), propertyNames[i]);
203 					if (propertyDescriptors[i]==null) {
204 						propertyDescriptors =null;
205 						throw new IntrospectionException("Bean "+bean.getClass().getName()+" does not contain property "+propertyNames[i]);
206 					}
207 				}
208 			}
209 		} else {
210 			PropertyDescriptor[] preProps = BeanIntrospector
211 				.getPropertyDescriptors(bean.getClass());
212 			propertyDescriptors = BeanIntrospector.getReadable(BeanIntrospector
213 				    .getWritable(preProps));
214 			propertyNames = BeanIntrospector.getPropertyNames(propertyDescriptors);
215 		}
216 
217 		final PropertiesTableModel m = (PropertiesTableModel)getModel();
218 		m.setPropertyNames(propertyNames);
219 		m.setPropertyTypes(BeanIntrospector.getPropertyTypes(
220 		        propertyDescriptors));
221 		m.setPropertyValues(BeanIntrospector.getPropertyValues(
222 		        propertyDescriptors, bean));
223 
224 		Method pcm = ClassIntrospector.getMethod(bean.getClass(),
225 			    "addPropertyChangeListener",
226 			    new Class[]{ PropertyChangeListener.class });
227 
228 		if (pcm != null) {
229 			pcm.invoke(bean,
230 			    new Object[]{
231 				    new PropertyChangeListener() {
232 						public void propertyChange(PropertyChangeEvent evt)
233 						{
234 							if (m.containsProperty(evt.getPropertyName())) {
235 								m.setValueForProperty(evt.getPropertyName(),
236 								        evt.getNewValue());
237 							}
238 						}
239 					}
240 			    });
241 		}
242 
243 		Object oldValue = fieldBean;
244 		fieldBean = bean;
245 		firePropertyChange("bean", oldValue, fieldBean);
246 		revalidate();
247 	}
248 
249 	/**
250 	 * Returns the propertyDescriptors.
251 	 *
252 	 * @return Returns the propertyDescriptors.
253 	 */
254 	public PropertyDescriptor[] getPropertyDescriptors()
255 	{
256 		return propertyDescriptors;
257 	}
258 
259 	/**
260 	 * Returns the propertyNames.
261 	 *
262 	 * @return Returns the propertyNames.
263 	 */
264 	public String[] getPropertyNames()
265 	{
266 		return propertyNames;
267 	}
268 }
269 
270 /* __oOo__ */