Revision 40970

View differences:

trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.symbology/org.gvsig.symbology.swing/org.gvsig.symbology.swing.api/src/main/java/org/gvsig/app/gui/styling/SymbolSelectorListModel.java
22 22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 23
 */
24 24
/* CVS MESSAGES:
25
*
26
* $Id: SymbolSelectorListModel.java 30838 2009-09-18 13:20:17Z cordinyana $
27
* $Log$
28
* Revision 1.11  2007-09-19 15:36:36  jaume
29
* removed unnecessary imports
30
*
31
* Revision 1.10  2007/09/17 15:27:21  jaume
32
* *** empty log message ***
33
*
34
* Revision 1.9  2007/08/07 11:22:06  jvidal
35
* javadoc
36
*
37
* Revision 1.8  2007/05/08 15:44:07  jaume
38
* *** empty log message ***
39
*
40
* Revision 1.7  2007/04/04 16:01:14  jaume
41
* *** empty log message ***
42
*
43
* Revision 1.6  2007/04/02 00:08:05  jaume
44
* *** empty log message ***
45
*
46
* Revision 1.2  2007/03/28 16:44:08  jaume
47
* *** empty log message ***
48
*
49
* Revision 1.1  2007/03/09 11:25:00  jaume
50
* Advanced symbology (start committing)
51
*
52
* Revision 1.4.2.4  2007/02/21 07:35:14  jaume
53
* *** empty log message ***
54
*
55
* Revision 1.4.2.3  2007/02/09 11:00:03  jaume
56
* *** empty log message ***
57
*
58
* Revision 1.4.2.2  2007/02/08 15:43:05  jaume
59
* some bug fixes in the editor and removed unnecessary imports
60
*
61
* Revision 1.4.2.1  2007/01/26 13:49:03  jaume
62
* *** empty log message ***
63
*
64
* Revision 1.4  2007/01/16 11:52:11  jaume
65
* *** empty log message ***
66
*
67
* Revision 1.7  2007/01/10 17:05:05  jaume
68
* moved to FMap and gvSIG
69
*
70
* Revision 1.6  2006/11/06 16:06:52  jaume
71
* *** empty log message ***
72
*
73
* Revision 1.5  2006/11/06 07:33:54  jaume
74
* javadoc, source style
75
*
76
* Revision 1.4  2006/11/02 17:19:28  jaume
77
* *** empty log message ***
78
*
79
* Revision 1.3  2006/10/30 19:30:35  jaume
80
* *** empty log message ***
81
*
82
* Revision 1.2  2006/10/26 16:31:21  jaume
83
* GUI
84
*
85
* Revision 1.1  2006/10/25 10:50:41  jaume
86
* movement of classes and gui stuff
87
*
88
* Revision 1.2  2006/10/24 22:26:18  jaume
89
* *** empty log message ***
90
*
91
* Revision 1.1  2006/10/24 16:31:12  jaume
92
* *** empty log message ***
93
*
94
*
95
*/
25
 *
26
 * $Id: SymbolSelectorListModel.java 30838 2009-09-18 13:20:17Z cordinyana $
27
 * $Log$
28
 * Revision 1.11  2007-09-19 15:36:36  jaume
29
 * removed unnecessary imports
30
 *
31
 * Revision 1.10  2007/09/17 15:27:21  jaume
32
 * *** empty log message ***
33
 *
34
 * Revision 1.9  2007/08/07 11:22:06  jvidal
35
 * javadoc
36
 *
37
 * Revision 1.8  2007/05/08 15:44:07  jaume
38
 * *** empty log message ***
39
 *
40
 * Revision 1.7  2007/04/04 16:01:14  jaume
41
 * *** empty log message ***
42
 *
43
 * Revision 1.6  2007/04/02 00:08:05  jaume
44
 * *** empty log message ***
45
 *
46
 * Revision 1.2  2007/03/28 16:44:08  jaume
47
 * *** empty log message ***
48
 *
49
 * Revision 1.1  2007/03/09 11:25:00  jaume
50
 * Advanced symbology (start committing)
51
 *
52
 * Revision 1.4.2.4  2007/02/21 07:35:14  jaume
53
 * *** empty log message ***
54
 *
55
 * Revision 1.4.2.3  2007/02/09 11:00:03  jaume
56
 * *** empty log message ***
57
 *
58
 * Revision 1.4.2.2  2007/02/08 15:43:05  jaume
59
 * some bug fixes in the editor and removed unnecessary imports
60
 *
61
 * Revision 1.4.2.1  2007/01/26 13:49:03  jaume
62
 * *** empty log message ***
63
 *
64
 * Revision 1.4  2007/01/16 11:52:11  jaume
65
 * *** empty log message ***
66
 *
67
 * Revision 1.7  2007/01/10 17:05:05  jaume
68
 * moved to FMap and gvSIG
69
 *
70
 * Revision 1.6  2006/11/06 16:06:52  jaume
71
 * *** empty log message ***
72
 *
73
 * Revision 1.5  2006/11/06 07:33:54  jaume
74
 * javadoc, source style
75
 *
76
 * Revision 1.4  2006/11/02 17:19:28  jaume
77
 * *** empty log message ***
78
 *
79
 * Revision 1.3  2006/10/30 19:30:35  jaume
80
 * *** empty log message ***
81
 *
82
 * Revision 1.2  2006/10/26 16:31:21  jaume
83
 * GUI
84
 *
85
 * Revision 1.1  2006/10/25 10:50:41  jaume
86
 * movement of classes and gui stuff
87
 *
88
 * Revision 1.2  2006/10/24 22:26:18  jaume
89
 * *** empty log message ***
90
 *
91
 * Revision 1.1  2006/10/24 16:31:12  jaume
92
 * *** empty log message ***
93
 *
94
 *
95
 */
96 96
package org.gvsig.app.gui.styling;
97 97

  
98 98
import java.io.File;
99 99
import java.io.FileFilter;
100
import java.util.ArrayList;
101
import java.util.Comparator;
102
import java.util.TreeSet;
103 100
import java.util.Vector;
104 101

  
105
import javax.swing.event.ListDataListener;
102
import javax.swing.AbstractListModel;
103
import javax.swing.SwingUtilities;
106 104

  
107
import org.slf4j.Logger;
108
import org.slf4j.LoggerFactory;
109

  
110 105
import org.gvsig.andami.messages.NotificationManager;
111 106
import org.gvsig.fmap.mapcontext.MapContextLocator;
112 107
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
113 108
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolException;
109
import org.gvsig.tools.exception.BaseException;
110
import org.gvsig.tools.locator.LocatorException;
111
import org.gvsig.tools.visitor.VisitCanceledException;
112
import org.gvsig.tools.visitor.Visitor;
114 113
import org.gvsig.utils.listManager.ListModel;
114
import org.slf4j.Logger;
115
import org.slf4j.LoggerFactory;
115 116

  
116

  
117 117
/**
118 118
 * Class SymbolSelectorListModel implements a list to select symbols.This list
119
 * has the property that allows the user to stablish a filter to accept or reject
120
 * elements for it from a directory which is also specified when teh SymbolSelectorModel
121
 * is created.
122
 *
123
 * @author jaume dominguez faus - jaume.dominguez@iver.es
124
 *
119
 * has the property that allows the user to stablish a filter to accept or
120
 * reject elements for it from a directory which is also specified when the
121
 * SymbolSelectorModel is created.
122
 * 
125 123
 */
126
public class SymbolSelectorListModel implements ListModel {
124
public class SymbolSelectorListModel extends AbstractListModel implements
125
		ListModel {
127 126

  
128
    private static Logger logger = LoggerFactory.getLogger(SymbolSelectorListModel.class);
127
	private static Logger logger = LoggerFactory.getLogger(SymbolSelectorListModel.class);
129 128
	private String fileExtension;
130
	protected FileFilter ffilter = new FileFilter() {
131
		public boolean accept(File pathname) {
132
			return pathname.getAbsolutePath().toLowerCase().endsWith(SymbolSelectorListModel.this.fileExtension);
133
		}
134
	};
135
	protected SelectorFilter sfilter;
136
	protected Vector<ISymbol> elements;
137
	private ArrayList listeners;
138
//	protected Object currentElement;
139
	protected File dir;
140 129

  
130
	private SelectorFilter sfilter;
131
	private Vector<ISymbol> elements;
132
	private File folder;
133

  
134
	
141 135
	/**
142 136
	 * <p>
143
	 * Creates a new instance of the model for the list in the Symbol Selector window
144
	 * where the symbols are stored in the <b>dir</b> (root directory) param.<br>
137
	 * Creates a new instance of the model for the list in the Symbol Selector
138
	 * window where the symbols are stored in the <b>dir</b> (root directory)
139
	 * param.<br>
145 140
	 * </p>
146
	 * <p>The <b>currentElement</b> defines which element is pre-selected.<br></p>
147
	 * <p>The <b>filter</b> is a user defined filter used to know which elements in
141
	 * <p>
142
	 * The <b>filter</b> is a user defined filter used to know which elements in
148 143
	 * the folder are accepted or rejected for this list and it is used to avoid
149
	 * mixing marker symbols for polygons for example.<br></p>
150
	 * <p><b>fileExtension</b> param defines the extension of the file to be parsed. This
151
	 * is like that to enable inheritance of this class to other file selector such
152
	 * as StyleSelector.
153
	 *
154
	 * @param dir, the root dir where symbols are located.
155
	 * @param currentElemet, the element to be pre-selected.
156
	 * @param filter, the filter used to show or hide some elements.
157
	 * @param fileExtension, file extension used for the files to be parsed.
144
	 * mixing marker symbols for polygons for example.<br>
145
	 * </p>
146
	 * <p>
147
	 * <b>fileExtension</b> param defines the extension of the file to be
148
	 * parsed. This is like that to enable inheritance of this class to other
149
	 * file selector such as StyleSelector.
150
	 * 
151
	 * @param dir
152
	 *            , the root dir where symbols are located.
153
	 * @param filter
154
	 *            , the filter used to show or hide some elements.
155
	 * @param fileExtension
156
	 *            , file extension used for the files to be parsed.
158 157
	 */
159
	public SymbolSelectorListModel(File dir, SelectorFilter filter, String fileExtension) {
158
	public SymbolSelectorListModel(File dir, SelectorFilter filter,
159
			String fileExtension) {
160 160
		this.fileExtension = fileExtension;
161
		this.dir = dir;
161
		this.folder = dir;
162 162
		this.sfilter = filter;
163 163
	}
164 164

  
165 165
	public Object remove(int i) throws ArrayIndexOutOfBoundsException {
166
		return elements.remove(i);
166
		ISymbol o = elements.remove(i);
167
		this.fireIntervalRemoved(this, i, i);
168
		return o;
167 169
	}
168 170

  
169 171
	public void insertAt(int i, Object o) {
170 172
		getObjects().insertElementAt((ISymbol) o, i);
173
		this.fireIntervalAdded(this, i, i);
171 174
	}
172 175

  
173
	public void add(Object o) {
174
		TreeSet map = new TreeSet(new Comparator() {
176
	protected boolean accepts(ISymbol symbol) {
177
		if (sfilter == null) {
178
			return true;
179
		}
180
		return sfilter.accepts(symbol);
181
	}
175 182

  
176
			public int compare(Object o1, Object o2) {
177
				// first will always be the current symbol
178
				
179
				ISymbol sym1 = (ISymbol) o1;
180
				ISymbol sym2 = (ISymbol) o2;
181
				if (sym1.getDescription() == null && sym2.getDescription() != null) return -1;
182
				if (sym1.getDescription() != null && sym2.getDescription() == null) return 1;
183
				if (sym1.getDescription() == null && sym2.getDescription() == null) return 1;
184

  
185
				int result = sym1.getDescription().compareTo(sym2.getDescription());
186
				return (result!=0) ? result: 1; /* this will allow adding symbols with
187
												   the same value for description than
188
												   a previous one. */
189
			}
190

  
191
		});
192

  
193
		map.addAll(elements);
194
		map.add(o);
195
		elements = new Vector(map);
196

  
183
	public void add(Object o) {
184
		ISymbol symbol = (ISymbol) o;
185
		if (!accepts(symbol)) {
186
			return;
187
		}
188
		Vector<ISymbol> e = this.getObjects();
189
		e.add((ISymbol) o);
190
		try {
191
			int n = e.size();
192
			this.fireIntervalAdded(this, n - 1, n);
193
		} catch (Exception ex) {
194
			// Do nothing.
195
		}
197 196
	}
198 197

  
199
	/**
200
	 * TODO: replace with the new Persistence API
201
	 */
202 198
	public Vector<ISymbol> getObjects() {
203 199
		if (elements == null) {
204
		
205
			try {
206
				ISymbol[] symbols = MapContextLocator.getSymbolManager()
207
						.loadSymbols(dir, ffilter);
208
				
209
				if (symbols == null) {
210
				    
211
				    logger.info("Warning: Did not load any symbol from folder: "
212
				        + dir.getAbsolutePath());
213
				    elements = new Vector<ISymbol>(0);
214
				    
215
				    
216
				} else {
217
	                elements = new Vector<ISymbol>(symbols.length);
218
	                for (int i = 0; i < symbols.length; i++) {
219
	                    if (sfilter == null || sfilter.accepts(symbols[i])) {
220
	                        elements.add(symbols[i]);
221
	                    }
222
	                }
200
			elements = new Vector<ISymbol>(0);
201
			FileFilter fileFiler = new FileFilter() {
202
				public boolean accept(File pathname) {
203
					return pathname.getAbsolutePath().toLowerCase().endsWith(fileExtension);
223 204
				}
224
				
225
			} catch (SymbolException e) {
226
				NotificationManager.addWarning(
227
						"Error loading the symbols from the folder: "
228
								+ dir.getAbsolutePath(), e);
229
			}
230

  
231
//			File[] ff = dir.listFiles(ffilter);
232
//			for (int i = 0; i < ff.length; i++) {
233
//
234
//				XMLEntity xml;
235
//				try {
236
//				
237
//					xml = new XMLEntity((XmlTag) XmlTag.unmarshal(XMLEncodingUtils.getReader(ff[i])));
238
//					ISymbol sym = SymbologyFactory.createSymbolFromXML(xml, ff[i].getName());
239
//					if (sfilter.accepts(sym))
240
//						add(sym);
241
//				} catch (MarshalException e) {
242
//					NotificationManager.
243
//						addWarning("Error in file ["+ff[i].getAbsolutePath()+"]. " +
244
//								"File corrupted! Skiping it...", e);
245
//				} catch (ValidationException e) {
246
//					NotificationManager.
247
//						addWarning("Error validating symbol file ["+ff[i].getAbsolutePath()+"].", e);
248
//				} catch (FileNotFoundException e) {
249
//					// unreachable code, but anyway...
250
//					NotificationManager.
251
//						addWarning("File not found: "+ ff[i].getAbsolutePath(), e);
252
//				}
253
//
254
//			}
205
			};
206
			Visitor visitor = new Visitor() {
207
				public void visit(final Object obj)
208
					throws VisitCanceledException, BaseException {
209
					SwingUtilities.invokeLater(new Runnable() {
210
						public void run() {
211
							add(obj);
212
						}
213
					});
214
				}
215
			};
216
			MapContextLocator.getSymbolManager().loadSymbols(folder,fileFiler,visitor);
217
			 
255 218
		}
256 219
		return elements;
257 220
	}
......
264 227
		return getObjects().get(index);
265 228
	}
266 229

  
267
	public void addListDataListener(ListDataListener l) {
268
		if (listeners == null)
269
			listeners = new ArrayList();
270
		listeners.add(l);
271
	}
272

  
273
	public void removeListDataListener(ListDataListener l) {
274
		if (listeners!=null)
275
			listeners.remove(l);
276
	}
277

  
278 230
}
279

  
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.mapcontext/org.gvsig.fmap.mapcontext.api/src/main/java/org/gvsig/fmap/mapcontext/rendering/symbols/impl/DefaultSymbolManager.java
48 48
import java.util.Map;
49 49
import java.util.Random;
50 50

  
51
import javax.swing.SwingUtilities;
52

  
51 53
import org.gvsig.fmap.mapcontext.MapContextRuntimeException;
52 54
import org.gvsig.fmap.mapcontext.impl.InvalidRegisteredClassException;
53 55
import org.gvsig.fmap.mapcontext.impl.RegisteredClassInstantiationException;
......
58 60
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
59 61
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolPreferences;
60 62
import org.gvsig.tools.ToolsLocator;
63
import org.gvsig.tools.exception.BaseException;
61 64
import org.gvsig.tools.persistence.PersistenceManager;
62 65
import org.gvsig.tools.persistence.PersistentState;
63 66
import org.gvsig.tools.persistence.exception.PersistenceException;
67
import org.gvsig.tools.task.AbstractMonitorableTask;
64 68
import org.gvsig.tools.task.SimpleTaskStatus;
65 69
import org.gvsig.tools.task.TaskStatusManager;
70
import org.gvsig.tools.visitor.VisitCanceledException;
71
import org.gvsig.tools.visitor.Visitor;
72
import org.slf4j.Logger;
73
import org.slf4j.LoggerFactory;
66 74

  
67 75
/**
68 76
 * Default {@link SymbolManager} implementation.
......
71 79
 */
72 80
public class DefaultSymbolManager implements SymbolManager {
73 81

  
82
	private static final Logger logger = LoggerFactory.getLogger(DefaultSymbolManager.class);
83
	
74 84
	private SymbolPreferences symbolPreferences =
75 85
			new DefaultSymbolPreferences();
76 86

  
......
147 157
		return null;
148 158
	}
149 159

  
160
	public class SymbolsLoaderTask extends AbstractMonitorableTask {
161
	
162
		private File folder;
163
		private FileFilter filter;
164
		private Visitor visitor;
165

  
166
		public SymbolsLoaderTask(File folder, FileFilter filter, Visitor visitor) {
167
			super("Load symbols", true);
168
			this.folder = folder; 
169
			this.filter = filter;
170
			this.visitor = visitor;
171
			if( folder == null ) {
172
				throw new IllegalArgumentException("folder is null");
173
			}
174
			if( visitor == null ) {
175
				throw new IllegalArgumentException("visitor is null");
176
			}
177
		}
178
		
179
		private File[] getFiles() {
180
			if (filter == null) {
181
				return folder.listFiles();
182
			} else {
183
				return folder.listFiles(filter);
184
			}
185
		}
186

  
187
		private String getVisitorName() {
188
			String s = visitor.toString() + "/" + visitor.getClass().getName();
189
			return s;
190
		}
191
		
192
		private void visit(final File file, final ISymbol symbol) throws VisitCanceledException {
193
			try {
194
				visitor.visit(symbol);
195
			} catch (BaseException e) {
196
				logger.warn("Can't call visit '"+getVisitorName()+"' to offer the symbol '"+file.getAbsolutePath()+"'.",e);
197
			}
198
		}
199
		
200
		public void run() {
201
			// TODO: add symbol caching
202
			try {
203
				if (folder.exists()) {
204
					taskStatus.setAutoremove(true);
205
					taskStatus.message("preparing");
206
					File[] symbolFiles = getFiles();
207

  
208
					if (symbolFiles != null) {
209
						taskStatus.setRangeOfValues(0, symbolFiles.length);
210

  
211
						/*
212
						 * Sorting by file name before loading. The problem here
213
						 * is that some descriptions can be empty, so sorting
214
						 * using description can have strange behavior. Sorting
215
						 * by file name is not very elegant, though.
216
						 */
217
						taskStatus.message("sorting");
218
						Arrays.sort(symbolFiles, new Comparator() {
219
							public int compare(Object o1, Object o2) {
220
								File f1 = (File) o1;
221
								File f2 = (File) o2;
222
								return f1.getName().compareTo(f2.getName());
223
							}
224
						});
225

  
226
						taskStatus.message("loading");
227
						for (int i = 0; i < symbolFiles.length; i++) {
228
							taskStatus.setCurValue(i);
229
							ISymbol symbol = null;
230
							try {
231
								symbol = loadSymbol(symbolFiles[i]);
232
								visit(symbolFiles[i], symbol);
233
							} catch (VisitCanceledException e) {
234
								break;
235
							} catch (SymbolException e) {
236
								logger.warn("Can't load symbol '"
237
										+ symbolFiles[i].getAbsolutePath()
238
										+ "'.", e);
239
							}
240
						}
241
						taskStatus.message("");
242

  
243
					}
244
				}
245

  
246
			} finally {
247
				taskStatus.terminate();
248
			}
249

  
250
		}
251
	}
252
	
253
	public void loadSymbols(File folder, FileFilter filter, Visitor visitor) {
254
		SymbolsLoaderTask task = new SymbolsLoaderTask(folder, filter, visitor);
255
		task.start();
256
	}
257

  
150 258
	public void saveSymbol(ISymbol symbol, String fileName, File folder)
151 259
			throws SymbolException {
152 260
		saveSymbol(symbol, fileName, folder, false);
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.mapcontext/org.gvsig.fmap.mapcontext.api/src/main/java/org/gvsig/fmap/mapcontext/rendering/symbols/SymbolManager.java
35 35
import org.gvsig.fmap.mapcontext.MapContextException;
36 36
import org.gvsig.fmap.mapcontext.MapContextRuntimeException;
37 37
import org.gvsig.tools.persistence.PersistenceManager;
38
import org.gvsig.tools.visitor.Visitor;
38 39

  
39 40
/**
40 41
 * Symbols management: creation, registration, etc.
......
74 75
	 */
75 76
	ISymbol[] loadSymbols(File folder, FileFilter filter)
76 77
			throws SymbolException;
77

  
78
	
79
	public void loadSymbols(File folder, FileFilter filter, Visitor visitor);
78 80
	/**
79 81
	 * Persists a {@link ISymbol} into the given folder, with the given file
80 82
	 * name.

Also available in: Unified diff