View Javadoc

1   package org.ximtec.igesture.tool.view.devicemanager;
2   
3   import java.lang.reflect.Field;
4   import java.lang.reflect.InvocationTargetException;
5   import java.lang.reflect.Method;
6   import java.util.ArrayList;
7   import java.util.Collection;
8   import java.util.Set;
9   
10  import javax.swing.JTable;
11  import javax.swing.event.ListSelectionListener;
12  import javax.swing.table.DefaultTableModel;
13  
14  /**
15   * This class represents a table containing objects of type T.
16   *  
17   * @author Bjorn Puype, bpuype@gmail.com
18   *
19   * @param <T>	kind of object the table contains
20   */
21  public class BasicTable<T> extends JTable {
22  
23  	//instead of keeping the original object in the map, when getting the object it could also be created with a constructor
24  	//this way the table needs less space, but it imposes extra constraints and difficulties on that constructor (order of passing)
25  	
26  	private ArrayList<T> mapping;
27  	
28  	/**
29  	 * Constructor
30  	 * @param headers	The column names, they should match with the field names of T.
31  	 */
32  	public BasicTable(String[] headers)
33  	{
34  		super();
35  		mapping = new ArrayList<T>();
36  		//create a model and add the headers to it
37  		DefaultTableModel tableModel= new BasicTableModel();
38  		for(String s : headers)
39  			tableModel.addColumn(s);
40  		//set this model as the table's model
41  		setModel(tableModel);
42  	}
43  	
44  	/**
45  	 * Add an item to the table
46  	 * @param item	The item to add.
47  	 */
48  	public void addItem(T item)
49  	{
50  		DefaultTableModel model = (DefaultTableModel)getModel();
51  		// get all the data corresponding with the headers
52  		Object[] data = new Object[model.getColumnCount()];
53  		for(int i = 0; i < model.getColumnCount(); i++)
54  		{
55  			String name = model.getColumnName(i);
56  			Object obj = null;
57  			try {
58  				Method method = item.getClass().getMethod("get"+name);
59  				obj = method.invoke(item);
60  			} catch (SecurityException e) {
61  				e.printStackTrace();
62  			} catch (NoSuchMethodException e) {
63  				e.printStackTrace();
64  			} catch (IllegalArgumentException e) {
65  				e.printStackTrace();
66  			} catch (IllegalAccessException e) {
67  				e.printStackTrace();
68  			} catch (InvocationTargetException e) {
69  				e.printStackTrace();
70  			}
71  			data[i] = obj;
72  		}
73  		//put the item in the mapping and add it to the model
74  		mapping.add(getRowCount(),item);
75  		model.insertRow(getRowCount(), data);
76  		
77  	}
78  	
79  	/**
80  	 * Get the currently selected item.
81  	 * @return	The selected item. Returns null if nothing is selected.
82  	 */
83  	public T getSelectedItem()
84  	{
85  		int i = getSelectedRow();
86  		if(i == -1)
87  			return null;
88  		else
89  			return mapping.get(i);
90  	}
91  	
92  	/**
93  	 * Remove the currently selected item.
94  	 * @return The item that is about to be removed. Returns null if nothing was selected.
95  	 */
96  	public T removeItem()
97  	{
98  		T item = getSelectedItem();
99  		if(item != null)
100 		{
101 			DefaultTableModel model = (DefaultTableModel)getModel();
102 			
103 			ArrayList<Integer> list = new ArrayList<Integer>();
104 			int i = getSelectedRow();
105 			//remove from mapping
106 			mapping.remove(i);
107 			//adjust the mapping so indexes will correspond with new row numbers
108 			mapping.trimToSize();
109 			//remove from model
110 			model.removeRow(i);
111 		}
112 		return item;
113 	}
114 	
115 	/**
116 	 * Update item in table.
117 	 * @param value	The new value.
118 	 * @param col	The column index in the table.
119 	 * @param item	The item to update, null if you do not want to update an item itself, only the table.
120 	 */
121 	public void updateItem(Object value, int col, T item)
122 	{
123 		int row = 0;
124 		if(item == null)
125 		{
126 			// update selected item in table model only
127 			row = getSelectedRow();
128 		}
129 		else // update item itself
130 			row = indexOf(item);
131 		
132 		if(row != -1)
133 		{
134 			// update table
135 			DefaultTableModel model = (DefaultTableModel) getModel();
136 			model.setValueAt(value, row, col);
137 			
138 			// update item that was passed
139 			if(item != null)
140 			{
141 				String name = getModel().getColumnName(col);
142 				
143 				try {
144 		//			Class[] args = new Class[]{String.class};//constraint: parametertype should be a String
145 		//			Method method = item.getClass().getMethod("set"+name,args);
146 		//			Object[] argv = new Object[]{value};
147 		//			method.invoke(item,argv);
148 					Field field = item.getClass().getDeclaredField(name.toLowerCase());
149 					field.setAccessible(true);
150 					field.set(item, value);
151 					
152 				} catch (SecurityException e) {
153 					e.printStackTrace();
154 				} catch (NoSuchFieldException e) {
155 					e.printStackTrace();
156 				} catch (IllegalArgumentException e) {
157 					e.printStackTrace();
158 				} catch (IllegalAccessException e) {
159 					e.printStackTrace();
160 		//		} catch (InvocationTargetException e) {
161 		//			e.printStackTrace();
162 				}
163 			}
164 		}
165 	}
166 	
167 	/**
168 	 * Remove all items from the table.
169 	 */
170 	public void removeAllItems()
171 	{
172 		//Clear the model.
173 		DefaultTableModel model = (DefaultTableModel)getModel();
174 		int rows = model.getRowCount();
175 		for(int row = 0; row < rows; row++)
176 		{
177 			model.removeRow(0);
178 		}
179 		//Clear the mapping
180 		mapping.clear();
181 	}
182 	
183 	/**
184 	 * Add multiple items to the table.
185 	 * @param items	The items to add.
186 	 */
187 	public void addItems(Set<T> items)
188 	{
189 		for(T item : items)
190 		{
191 			addItem(item);
192 		}
193 	}
194 	
195 	/**
196 	 * Get all items in the table.
197 	 * @return	A Collection of the items in the table.
198 	 */
199 	public Collection<T> getItems()
200 	{
201 		return mapping;
202 	}
203 	
204 	/**
205 	 * Get the index of the item.
206 	 * @param o	The item.
207 	 * @return	The index of the item. Returns -1 if not in the table.
208 	 */
209 	private int indexOf(Object o)
210 	{
211 		return mapping.indexOf(o);
212 	}
213 	
214 	/**
215 	 * Add a selection listener to the table.
216 	 * @param l	The listener.
217 	 */
218 	public void addListSelectionListener(ListSelectionListener l)
219 	{
220 		getSelectionModel().addListSelectionListener(l);
221 	}
222 	
223 	/**
224 	 * This class represents the model of the table.
225 	 * @author Bjönöype, bpuype@gmail.com
226 	 *
227 	 */
228 	class BasicTableModel extends DefaultTableModel
229 	{
230 		//make the table uneditable
231 		@Override
232 		public boolean isCellEditable(int row, int col)
233         { 
234 			return false; 
235 		}
236 
237 		//use checkboxes to render booleans
238 		@Override
239 		public Class getColumnClass(int c) {
240             return getValueAt(0, c).getClass();
241         }
242 
243 	}
244 }