Statistics
| Revision:

root / trunk / extensions / extRasterTools-SE / src / org / gvsig / rastertools / filter / FilterListener.java @ 12333

History | View | Annotate | Download (19.3 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.rastertools.filter;
20

    
21
import java.awt.Component;
22
import java.awt.Dimension;
23
import java.awt.Graphics2D;
24
import java.awt.event.ActionEvent;
25
import java.awt.event.ActionListener;
26
import java.awt.geom.AffineTransform;
27
import java.awt.geom.Dimension2D;
28
import java.io.File;
29
import java.util.ArrayList;
30
import java.util.EventObject;
31
import java.util.Hashtable;
32

    
33
import javax.swing.JFileChooser;
34
import javax.swing.JOptionPane;
35
import javax.swing.ListModel;
36

    
37
import org.gvsig.fmap.layers.FLyrRasterSE;
38
import org.gvsig.gui.beans.imagenavigator.IClientImageNavigator;
39
import org.gvsig.gui.beans.incrementabletask.IncrementableTask;
40
import org.gvsig.gui.beans.propertiespanel.PropertiesComponent;
41
import org.gvsig.gui.beans.propertiespanel.PropertiesComponentListener;
42
import org.gvsig.gui.beans.propertiespanel.PropertyStruct;
43
import org.gvsig.gui.beans.treelist.event.TreeListChangeEvent;
44
import org.gvsig.gui.beans.treelist.event.TreeListEvent;
45
import org.gvsig.gui.beans.treelist.listeners.TreeListChangeListener;
46
import org.gvsig.gui.beans.treelist.listeners.TreeListComponentListener;
47
import org.gvsig.raster.dataset.GeoRasterWriter;
48
import org.gvsig.raster.dataset.MultiRasterDataset;
49
import org.gvsig.raster.dataset.Params;
50
import org.gvsig.raster.dataset.Params.Param;
51
import org.gvsig.raster.grid.filter.IRasterFilterListManager;
52
import org.gvsig.raster.grid.filter.RasterFilter;
53
import org.gvsig.raster.grid.filter.RasterFilterList;
54
import org.gvsig.raster.grid.filter.RasterFilterListManager;
55
import org.gvsig.raster.grid.render.Rendering;
56
import org.gvsig.raster.shared.Extent;
57
import org.gvsig.raster.shared.ViewPortData;
58
import org.gvsig.rastertools.RasterModule;
59
import org.gvsig.rastertools.filter.ui.FilterPanel;
60

    
61
import com.iver.andami.PluginServices;
62
import com.iver.andami.Utilities;
63
import com.iver.andami.ui.mdiManager.IWindow;
64
import com.iver.cit.gvsig.exceptions.layers.LoadLayerException;
65
import com.iver.cit.gvsig.fmap.ViewPort;
66
import com.iver.cit.gvsig.fmap.layers.FLayer;
67
import com.iver.cit.gvsig.project.documents.view.gui.View;
68
/**
69
 * <code>FilterListener</code> es la clase donde se procesar? gran parte del
70
 * c?digo que controla el panel para el manejo de un layer en la aplicaci?n de
71
 * filtros.
72
 *
73
 * @version 24/05/2007
74
 * @author Borja S?nchez Zamorano (borja.sanchez@iver.es)
75
 */
76
public class FilterListener implements ActionListener, IClientImageNavigator, TreeListComponentListener, TreeListChangeListener, PropertiesComponentListener {
77
        FilterPanel                                filterPanel        = null;
78
        public int                                actualParam        = -1;
79
        public ArrayList        paramsList        = new ArrayList();
80

    
81
        public class ParamStruct {
82
                String filterName = null;
83
                Params filterParam = null;
84
                Class filterClass = null;
85

    
86
                /**
87
                 * @return the filterName
88
                 */
89
                public String getFilterName() {
90
                        return filterName;
91
                }
92

    
93
                /**
94
                 * @param filterName the filterName to set
95
                 */
96
                public void setFilterName(String filterName) {
97
                        this.filterName = filterName;
98
                }
99

    
100
                /**
101
                 * @return the filterParam
102
                 */
103
                public Params getFilterParam() {
104
                        return filterParam;
105
                }
106

    
107
                /**
108
                 * @param filterParam the filterParam to set
109
                 */
110
                public void setFilterParam(Params filterParam) {
111
                        this.filterParam = filterParam;
112
                }
113

    
114
                /**
115
                 * @return the filterClass
116
                 */
117
                public Class getFilterClass() {
118
                        return filterClass;
119
                }
120

    
121
                /**
122
                 * @param filterClass the filterClass to set
123
                 */
124
                public void setFilterClass(Class filterClass) {
125
                        this.filterClass = filterClass;
126
                }
127
        }
128

    
129
        /**
130
         * Construye un FilterListener especificando el FilterPanel asociado
131
         * @param fp
132
         */
133
        public FilterListener(FilterPanel fp) {
134
                filterPanel = fp;
135
        }
136

    
137
        /**
138
         * Asignamos los valores del PropertiesComponent al Params seleccionado
139
         */
140
        public void RefreshDataProperties() {
141
                if (actualParam == -1) return;
142

    
143
                ArrayList listValues = getFilterPanel().getPropertiesComponent().getValues();
144

    
145
                Params params = ((ParamStruct) paramsList.get(actualParam)).getFilterParam();
146
                for (int j=0; j<listValues.size(); j++) {
147
                        PropertyStruct ps = (PropertyStruct) listValues.get(j);
148
                        params.changeParamValue(ps.getKey(), ps.getNewValue().toString());
149
                }
150
        }
151

    
152
        /**
153
         * Obtener la posici?n del Param seleccionado en el ArrayList
154
         * @param filterName
155
         * @return
156
         */
157
        private int getParamSelected(String filterName) {
158
                for (int i = 0; i < paramsList.size(); i++) {
159
                        if (((ParamStruct) paramsList.get(i)).getFilterName().equals(filterName))
160
                                return i;
161
                }
162
                return -1;
163
        }
164

    
165
        /**
166
         * Cambiar el panel de propiedades central por el nuevo panel, segun el filtro
167
         * seleccionado que se pasa por par?metro.
168
         * @param filter
169
         */
170
        public void changePanel(String filter) {
171
                int posParam = getParamSelected(filter);
172

    
173
                RefreshDataProperties();
174
                actualParam = posParam;
175

    
176
                PropertiesComponent propertiesComponent = new PropertiesComponent();
177

    
178
                if (posParam != -1) {
179

    
180
                        Params params = ((ParamStruct) paramsList.get(actualParam)).getFilterParam();
181
                        if (params != null) {
182
                                for (int i = 0; i < params.getNumParams(); i++) {
183
                                        Param p = params.getParam(i);
184
                                        String name = p.id;
185
                                        String key = p.id;
186
                                        if (name.equals("FilterName")) continue;
187
                                        Object[] types = null;
188
                                        int selectedValue = 0;
189

    
190
                                        switch (params.getParam(i).type) {
191
                                                case Params.CHECK:
192
                                                        propertiesComponent.addValue(name, key, new Boolean((String) p.defaultValue), types);
193
                                                        break;
194
                                                case Params.CHOICE:
195
                                                        ArrayList list = new ArrayList();
196
                                                        for (int j = 0; j < p.list.length; j++) {
197
                                                                list.add(p.list[j]);
198
                                                                if (((String) p.defaultValue).compareTo(p.list[j]) == 0)
199
                                                                        selectedValue = j;
200
                                                        }
201
                                                        types = new Object[] { new Integer(PropertiesComponent.TYPE_COMBO), list };
202
                                                        propertiesComponent.addValue(name, key, new Integer(selectedValue), types);
203
                                                        break;
204
                                                case Params.SLIDER:
205
                                                        types = new Object[]{new Integer(PropertiesComponent.TYPE_SLIDER), new Integer(p.list[0]), new Integer(p.list[1])};
206
                                                        propertiesComponent.addValue(name, key, new Integer((int) Math.round(new Double((String) p.defaultValue).doubleValue())), types);
207
                                                        break;
208
                                                default:
209
                                                        propertiesComponent.addValue(params.getParam(i).id, params.getParam(i).id, params.getParam(i).defaultValue, null);
210
                                                        break;
211
                                        }
212
                                }
213
                        }
214
                }
215
                getFilterPanel().setNewPropertiesComponent(propertiesComponent, filter);
216
        }
217

    
218
        /**
219
         * A?adir un nuevo Params a la lista de Params que podemos manejar. Un Params
220
         * equivale a un filtro cargado. El hecho de trabajar con Params y no con
221
         * filtros, simplifica totalmente el panel. Sin tener que depender de los
222
         * filtros nada m?s que para el momento de dibujado o guardado.
223
         * @param name
224
         * @param params
225
         * @param classFilter
226
         */
227
        public void addNewParam(String name, Params params, Class classFilter) {
228
                ParamStruct param = new ParamStruct();
229
                param.setFilterName(name);
230
                param.setFilterParam(params);
231
                param.setFilterClass(classFilter);
232
                paramsList.add(param);
233
        }
234

    
235
        /*
236
         * (non-Javadoc)
237
         * @see org.gvsig.gui.beans.propertiespanel.PropertiesComponentListener#actionChangeProperties(java.util.EventObject)
238
         */
239
        public void actionChangeProperties(EventObject e) {
240
                RefreshDataProperties();
241
                getFilterPanel().refreshPreview();
242
        }
243

    
244
        /*
245
         * (non-Javadoc)
246
         * @see org.gvsig.gui.beans.treelist.listeners.TreeListChangeListener#actionChangeSelection(org.gvsig.gui.beans.treelist.event.TreeListChangeEvent)
247
         */
248
        public void actionChangeSelection(TreeListChangeEvent e) {
249
                changePanel(e.getItem());
250
        }
251

    
252
        /*
253
         * (non-Javadoc)
254
         * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
255
         */
256
        public void actionPerformed(ActionEvent e) {
257
                getFilterPanel().refreshPreview();
258
        }
259

    
260
        /*
261
         * (non-Javadoc)
262
         * @see org.gvsig.gui.beans.treelist.listeners.TreeListComponentListener#elementAdded(org.gvsig.gui.beans.treelist.event.TreeListEvent)
263
         */
264
        public void elementAdded(TreeListEvent e) {
265
                getFilterPanel().refreshPreview();
266
        }
267

    
268
        /*
269
         * (non-Javadoc)
270
         * @see org.gvsig.gui.beans.treelist.listeners.TreeListComponentListener#elementMoved(org.gvsig.gui.beans.treelist.event.TreeListEvent)
271
         */
272
        public void elementMoved(TreeListEvent e) {
273
                getFilterPanel().refreshPreview();
274
        }
275

    
276
        /*
277
         * (non-Javadoc)
278
         * @see org.gvsig.gui.beans.treelist.listeners.TreeListComponentListener#elementRemoved(org.gvsig.gui.beans.treelist.event.TreeListEvent)
279
         */
280
        public void elementRemoved(TreeListEvent e) {
281
                getFilterPanel().refreshPreview();
282
        }
283

    
284
        /**
285
         * @return the paramsList
286
         */
287
        public ArrayList getParamsList() {
288
                return paramsList;
289
        }
290

    
291
        /**
292
         * Devuelve la ruta del fichero donde se va a guardar, en caso de guardarse
293
         * en memoria, calcula el nombre sin preguntar y devuelve la ruta.
294
         * @return
295
         */
296
        public String getFileSelected() {
297
                String path = "";
298
                if (getFilterPanel().getRadioFileGenerate().isSelected()) {
299
                        JFileChooser chooser = new JFileChooser(RasterModule.getPath());
300
                        chooser.setDialogTitle(PluginServices.getText(this, "seleccionar_fichero"));
301

    
302
                        //A?adimos las extensiones que hayan sido registradas en el driver
303
                        String[] extList = GeoRasterWriter.getDriversExtensions();
304
                        for(int i=0;i<extList.length;i++)
305
                                chooser.addChoosableFileFilter(new WriterFilter(extList[i]));
306

    
307
                        if (chooser.showOpenDialog(getFilterPanel()) != JFileChooser.APPROVE_OPTION)
308
                                return null;
309

    
310
                        String fName = chooser.getSelectedFile().toString();
311
                        String ext = ((WriterFilter)chooser.getFileFilter()).getDescription();
312

    
313
                        ext = ext.toLowerCase().substring(ext.lastIndexOf(".") + 1, ext.length());
314

    
315
                        if ((fName != null) && !fName.equals(""))
316
                                if (!fName.endsWith("." + ext))
317
                                        fName = fName + "." + ext;
318

    
319
                        RasterModule.setPath(chooser.getSelectedFile().getPath().substring(0, chooser.getSelectedFile().getPath().lastIndexOf(File.separator)));
320
                        path = fName;
321
                } else {
322
                        path = Utilities.createTempDirectory() + File.separator + getFilterPanel().getFilenameTextField().getText() + ".tif";
323
                        filterPanel.setNewLayerText();
324
                }
325
                return path;
326
        }
327

    
328
        /**
329
         * Aqui se seleccionan que filtros se van a aplicar y se devuelven en forma
330
         * de ArrayList tanto para el dibujado como cuando aceptan o aplican el panel.
331
         * @param rendering
332
         * @return
333
         */
334
        public ArrayList applyFilters(Rendering rendering) {
335
                ArrayList listFilterUsed = new ArrayList();
336

    
337
                RasterFilterList filterList = new RasterFilterList();
338
                RasterFilterListManager stackManager = new RasterFilterListManager(filterList);
339

    
340
                // Conservamos filtros no visibles ya existentes
341
                ArrayList filtersInit = getFilterPanel().getFilterStatus();
342
                for (int i = 0; i < filtersInit.size(); i++) {
343
                        // Si es visible no hacemos nada
344
                        if (((RasterFilter) filtersInit.get(i)).isVisible())
345
                                continue;
346

    
347
                        RasterFilter obj = null;
348
                        for (int j = 0; j < stackManager.getRasterFilterList().size(); j++) {
349
                                Class classFilter = (Class) stackManager.getRasterFilterList().get(j);
350
                                try {
351
                                        obj = (RasterFilter) classFilter.newInstance();
352
                                        if (obj.getName().equals(((RasterFilter) filtersInit.get(i)).getName()))
353
                                                break;
354
                                } catch (InstantiationException e) {
355
                                        e.printStackTrace();
356
                                } catch (IllegalAccessException e) {
357
                                        e.printStackTrace();
358
                                }
359
                        }
360

    
361
                        // Si no encontramos el filtro apropiado, nos olvidamos de el
362
                        if (obj == null)
363
                                continue;
364

    
365
                        // Si no es visible tenemos que conservar el filtro
366
                        try {
367
                                Params params = (Params) ((RasterFilter) filtersInit.get(i)).getUIParams(((RasterFilter) filtersInit.get(i)).getName()).clone();
368
                                // A?ado el parametro RenderBands a los parametros del filtro
369
                                String rgb = rendering.getRenderBands()[0] + " " + rendering.getRenderBands()[1] + " " + rendering.getRenderBands()[2];
370
                                params.setParam("RenderBands", rgb, 0, null);
371

    
372
                                ParamStruct newParam = new ParamStruct();
373
                                newParam.setFilterClass(obj.getClass());
374
                                newParam.setFilterName(((RasterFilter) filtersInit.get(i)).getName());
375
                                newParam.setFilterParam(params);
376
                                listFilterUsed.add(newParam);
377
                        } catch (CloneNotSupportedException e) {
378
                        }
379
                }
380

    
381
                // Metemos los filtros seleccionados en el panel
382
                ListModel list = getFilterPanel().getTreeListContainer().getListModel();
383
                for (int i = 0; i < list.getSize(); i++) {
384
                        Hashtable hastTable = getFilterPanel().getTreeListContainer().getMap();
385
                        for (int j = 0; j < paramsList.size(); j++) {
386
                                boolean active = true;
387
                                Param param = ((ParamStruct) paramsList.get(j)).getFilterParam().getParamById(PluginServices.getText(this, "enabled"));
388
                                if ((param != null) && ((new Boolean((String) param.defaultValue).booleanValue()) == false))
389
                                        active = false;
390
                                if (active) {
391
                                        if (((ParamStruct) paramsList.get(j)).getFilterName().equals(hastTable.get(list.getElementAt(i)))) {
392
                                                try {
393
                                                        Params params = (Params) ((ParamStruct) paramsList.get(j)).getFilterParam().clone();
394
                                                        // A?ado el parametro RenderBands a los parametros del filtro
395
                                                        String rgb = rendering.getRenderBands()[0] + " " + rendering.getRenderBands()[1] + " " + rendering.getRenderBands()[2];
396
                                                        params.setParam("RenderBands", rgb, 0, null);
397

    
398
                                                        ParamStruct newParam = new ParamStruct();
399
                                                        newParam.setFilterClass(((ParamStruct) paramsList.get(j)).getFilterClass());
400
                                                        newParam.setFilterName(((ParamStruct) paramsList.get(j)).getFilterName());
401
                                                        newParam.setFilterParam(params);
402
                                                        listFilterUsed.add(newParam);
403
                                                } catch (CloneNotSupportedException e) {
404
                                                }
405
                                        }
406
                                }
407
                        }
408
                }
409
                return listFilterUsed;
410
        }
411

    
412
        /*
413
         * (non-Javadoc)
414
         * @see org.gvsig.gui.beans.imagenavigator.IClientImageNavigator#drawImage(java.awt.Graphics2D, double, double, double, double, double, int, int)
415
         */
416
        public void drawImage(Graphics2D g, double x1, double y1, double x2, double y2, double zoom, int width, int height) {
417
                if (getFilterPanel().getLayer() == null)
418
                        return;
419

    
420
                Rendering rendering = ((FLyrRasterSE) getFilterPanel().getLayer()).getRender();
421

    
422
                if ((rendering == null) || ((x2 - x1) == 0.0) || ((y2 - y1) == 0.0))
423
                        return;
424

    
425
                rendering.getFilterList().pushStatus();
426

    
427
                rendering.getFilterList().clear();
428

    
429
                if (getFilterPanel().getCBShowFilters().isSelected()) {
430
                        RasterFilterList filterList = rendering.getFilterList();
431
                        RasterFilterListManager stackManager = new RasterFilterListManager(filterList);
432

    
433
                        ArrayList listFilterUsed = applyFilters(rendering);
434
                        for (int i = 0; i < listFilterUsed.size(); i++) {
435
                                IRasterFilterListManager filterManager = stackManager.getManagerByFilterClass(((ParamStruct) listFilterUsed.get(i)).getFilterClass());
436
                                filterManager.addFilter(((ParamStruct) listFilterUsed.get(i)).getFilterClass(), ((ParamStruct) listFilterUsed.get(i)).getFilterParam());
437
                        }
438
                }
439

    
440
                ViewPort vp = new ViewPort(null);
441

    
442
                Dimension2D dimension = new Dimension(width, height);
443
                Extent extent = new Extent(x1, y1, x2, y2);
444

    
445
                ViewPortData vp2 = new ViewPortData(vp.getProjection(), extent, dimension);
446
                vp2.setMat(new AffineTransform(zoom, 0.0, 0.0, zoom, -x1*zoom, -y1*zoom));
447

    
448
                Extent extent2 = ((FLyrRasterSE) getFilterPanel().getLayer()).getDatasource().getExtent();
449

    
450
                AffineTransform trans = g.getTransform();
451
                // Calcular cuanto sobresale la imagen y rectificar ese desplazamiento
452
                if (y1 > extent2.maxY()) {
453
                        g.translate(0.0, (-(extent2.maxY() - y1) * zoom)*2.0);
454
                }
455

    
456
                rendering.draw(g, vp2);
457
                g.setTransform(trans);
458

    
459
                rendering.getFilterList().popStatus();
460
        }
461

    
462
        /**
463
         * Que acciones se ejecutaran al haber presionado el bot?n aceptar o aplicar
464
         */
465
        public void accept() {
466
                MultiRasterDataset multiRasterDataset = (MultiRasterDataset)((FLyrRasterSE) getFilterPanel().getLayer()).getGeoRasterMultiDataset();
467
                if (multiRasterDataset == null)
468
                        return;
469

    
470
                String path = null;
471
                if (!getFilterPanel().getRadioOnlyView().isSelected()) {
472
                        path = getFileSelected();
473
                        if (path == null)
474
                                return;
475
                }
476

    
477
                Rendering rendering = ((FLyrRasterSE) getFilterPanel().getLayer()).getRender();
478

    
479
                // Array para guardar los filtros que se van a usar en forma de ParamStruct
480
                ArrayList listFilterUsed = applyFilters(rendering);
481

    
482
                if (filterPanel.getRadioOnlyView().isSelected()) {
483
                        FilterProcess.addSelectedFilters(rendering.getFilterList(), listFilterUsed);
484
                        getFilterPanel().getLayer().getMapContext().invalidate();
485
                } else {
486
                        FilterProcess filterProcess = new FilterProcess(this, path, multiRasterDataset, listFilterUsed);
487
                        IncrementableTask incrementableTask = new IncrementableTask(filterProcess);
488
                        filterProcess.setIncrementableTask(incrementableTask);
489
                        incrementableTask.showWindow();
490

    
491
                        filterProcess.start();
492
                        incrementableTask.start();
493
                }
494
        }
495

    
496
        /**
497
         * Devuelve el FilterPanel asociado al FilterListener
498
         * @return
499
         */
500
        public FilterPanel getFilterPanel() {
501
                return filterPanel;
502
        }
503

    
504
        /**
505
         * Acciones que se realizan al finalizar de crear los recortes de imagen.
506
         * Este m?todo es llamado por el thread TailRasterProcess al finalizar.
507
         */
508
        public void loadLayerInToc(String fileName) {
509
                if (!getFilterPanel().getRadioNewLayer().isSelected())
510
                        return;
511
                if(!new File(fileName).exists())
512
                        return;
513
                // seleccionamos la vista de gvSIG
514
                com.iver.cit.gvsig.project.documents.view.gui.View theView = null;
515
                try {
516
                        IWindow[] allViews = PluginServices.getMDIManager().getAllWindows();
517
                        for (int i = 0; i < allViews.length; i++) {
518
                                if (allViews[i] instanceof com.iver.cit.gvsig.project.documents.view.gui.View
519
                                                && PluginServices.getMDIManager().getWindowInfo((View) allViews[i])
520
                                                                .getTitle().equals(getFilterPanel().getViewName()))
521
                                        theView = (com.iver.cit.gvsig.project.documents.view.gui.View) allViews[i];
522
                        }
523
                        if (theView == null)
524
                                return;
525
                } catch (ClassCastException ex) {
526
                        // logger.error(PluginServices.getText(this,"cant_get_view "), ex);
527
                        return;
528
                }
529

    
530
                // Cargamos las capas
531
                theView.getMapControl().getMapContext().beginAtomicEvent();
532

    
533
                //Driver driver = LayerFactory.getDM().getDriver("gvSIG Raster Driver");
534
                int endIndex = fileName.lastIndexOf(".");
535
                if (endIndex < 0)
536
                        endIndex = fileName.length();
537
                FLayer lyr = null;
538
                try {
539
                        lyr = FLyrRasterSE.createLayer(fileName.substring(
540
                                        fileName.lastIndexOf(File.separator) + 1, endIndex),
541
                                        new File(fileName), theView.getMapControl().getProjection());
542
                } catch (LoadLayerException e) {
543
                        JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
544
                                        PluginServices.getText(this, "error_cargar_capa"));
545
                }
546
                theView.getMapControl().getMapContext().getLayers().addLayer(lyr);
547
                theView.getMapControl().getMapContext().endAtomicEvent();
548

    
549
                getFilterPanel().getLayer().getMapContext().invalidate();
550
        }
551
}
552

    
553
/**
554
 * @author Nacho Brodin <brodin_ign@gva.es>
555
 * Filtro para el selector de formatos de escritura
556
 */
557
class WriterFilter extends javax.swing.filechooser.FileFilter {
558
        private String                                filter;
559

    
560
        public WriterFilter(String fil) {
561
                this.filter = fil;
562
        }
563

    
564
        public boolean accept(File f) {
565
                return f.isDirectory() || f.getName().toLowerCase().endsWith("." + filter);
566
        }
567

    
568
        public String getDescription() {
569
                return "." + filter;
570
        }
571
}