Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/greenstone/gatherer/gui/Filter.java


1   /**
2    *#########################################################################
3    *
4    * A component of the Gatherer application, part of the Greenstone digital
5    * library suite from the New Zealand Digital Library Project at the
6    * University of Waikato, New Zealand.
7    *
8    * <BR><BR>
9    *
10   * Author: John Thompson, Greenstone Digital Library, University of Waikato
11   *
12   * <BR><BR>
13   *
14   * Copyright (C) 1999 New Zealand Digital Library Project
15   *
16   * <BR><BR>
17   *
18   * This program is free software; you can redistribute it and/or modify
19   * it under the terms of the GNU General Public License as published by
20   * the Free Software Foundation; either version 2 of the License, or
21   * (at your option) any later version.
22   *
23   * <BR><BR>
24   *
25   * This program is distributed in the hope that it will be useful,
26   * but WITHOUT ANY WARRANTY; without even the implied warranty of
27   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28   * GNU General Public License for more details.
29   *
30   * <BR><BR>
31   *
32   * You should have received a copy of the GNU General Public License
33   * along with this program; if not, write to the Free Software
34   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35   *########################################################################
36   */
37  package org.greenstone.gatherer.gui;
38  
39  import java.awt.*;
40  import java.awt.event.*;
41  import java.util.*;
42  import java.util.regex.*;
43  import javax.swing.*;
44  import javax.swing.tree.*;
45  import org.greenstone.gatherer.Dictionary;
46  import org.greenstone.gatherer.Gatherer;
47  import org.greenstone.gatherer.file.FileSystemModel;
48  import org.greenstone.gatherer.gui.tree.DragTree;
49  
50  /** <p>This object allows the user to set a filter on one of the workspace trees, specifying a preset type, or a regular expression that a files must match to be in the tree. Note that all directories are included. This class includes the controls for editing the filter. The trick is that several instances of the Filter class can share the same internal data (termed a 'run' of filters), so that the filter set on the CollectionPane and the MetaEditPane are virtually the same.</p>
51   * <p>The regular expression typed uses '*' as a wildcard character (equivalent to '.*'), and does not use '.' to match any single character (use '?' instead).</p>
52   * @author John Thompson, Greenstone Digital Library, University of Waikato
53   * @version 2.3
54   */
55  public class Filter
56      extends JPanel {
57      /** The other filters in this run of filters, used to ensure they all show the same thing. */
58      private ArrayList others = null;
59      /** Is this the first filter of this run of filters created (later filters will share the same information). */
60      private boolean first = true;
61      /** Prevent any changes we make in the class from causing events which we then process causing events... */
62      private boolean ignore = false;
63      /** A reference to ourselves so inner classes can refer to us. */
64      private Filter this_filter = null;
65      /** The check box to enable/disable filter. */
66      private JCheckBox checkbox = null;
67      /** The editable combobox where you either choose a predefined filter, or type a new pseudo-regular expression. */
68      private GComboBox combobox = null;
69      /** The label shown on the filter controls. */
70      private JLabel label = null;
71      /** A reference to the tree this filter is being applied to. */
72      private DragTree tree = null;
73      /** The default size for the label. */
74      static final private Dimension SIZE = new Dimension(100,25);
75      /** Preprogrammed default filters. */
76      static final private String DEFAULTS[] = {"^.*\\.html?$", "^.*\\.xml$", "^.*\\.txt$", "(^.*\\.jpe?g$)|(^.*\\.png$)|(^.*\\.gif$)|(^.*\\.bmp$)|(^.*\\.tif$)"};
77  
78      /** Constructor.
79       * @param tree A reference to the <strong>JTree</strong> being affected.
80       */
81      public Filter(DragTree tree) {
82    this(tree, null);
83      }
84  
85      /** Constructor.
86       * @param tree A reference to the <strong>JTree</strong> being affected.
87       * @param others An <strong>ArrayList</strong> of the other Filters already in this run.
88       */
89      public Filter(DragTree tree, ArrayList others) {
90    super();
91    if (others == null) {
92        others = new ArrayList();
93    }
94    this.others = others;
95    this.others.add(this);
96    this.this_filter = this;
97    this.tree = tree;
98    // Create components.
99    combobox = new GComboBox();
100   combobox.add(new Entry());
101   for(int i = 0; i < DEFAULTS.length; i++) {
102       try {
103     Entry entry = new Entry(Dictionary.get("Filter." + i), Pattern.compile(DEFAULTS[i]));
104     combobox.add(entry);
105       }
106       catch (Exception error) {
107     error.printStackTrace();
108       }
109   }
110   combobox.setEditable(true);
111   label = new JLabel();
112   label.setPreferredSize(SIZE);
113   Dictionary.setText(label, "Filter.Filter_Tree");
114   // Add listeners.
115   combobox.addActionListener(new ComboBoxListener());
116   // Layout.
117   label.setBorder(BorderFactory.createEmptyBorder(0,0,0,5));
118 
119   setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
120   setLayout(new BorderLayout());
121   add(label, BorderLayout.WEST);
122   add(combobox, BorderLayout.CENTER);
123     }
124     /** Retrieve the combobox associated with this filter.
125      * @return A <strong>GComboBox</strong>.
126      */
127     public GComboBox getComboBox() {
128   return combobox;
129     }
130 
131     /** Used to restore the filter state to enabled, the normal state during collection editing.
132      * @param state The new state for the filter. <i>true</i> for enabled, <i>false</i> otherwise.
133      */
134     public void setEnabled(boolean state) {
135   ignore = true;
136   combobox.setEditable(state);
137   combobox.setEnabled(state);
138   ignore = false;
139     }
140 
141     /** Set the combobox model for this filter.
142      * @param model The new <strong>ComboBoxModel</strong> to use.
143      */
144     public void setComboBoxModel(ComboBoxModel model) {
145   combobox.setModel(model);
146     }
147 
148     /** Ensure that a certain entry is selected from the combobox.
149      * @param selection The <strong>Entry</strong> that should be selected.
150      */
151     public void setComboBoxSelection(Entry selection) {
152   ignore = true;
153   combobox.setSelectedItem(selection);
154   ignore = false;
155     }
156 
157     /** Set to signify that this filter is the first in a new run of filters.
158      * @param first <i>true</i> if this is the first filter in a run, <i>false</i> if it will just be added to the current run.
159      */
160     public void setFirst(boolean first) {
161   this.first = first;
162     }
163 
164     /** Spawn produces a copy of this filter, which has new controls, but shares listeners with this filter, and vice versa. Thus we can have two synchronized, but differing sets of controls.
165      * @param tree_spawn The <strong>JTree</strong> this filter will affect.
166      * @return A new <strong>Filter</strong> which is in the same run as this filter.
167      */
168     public Filter spawn(DragTree tree_spawn) {
169   Filter filter = new Filter(tree_spawn, others);
170   filter.setFirst(false); // No spawned copies should generate error messages, but fail silently.
171   filter.setComboBoxModel(combobox.getModel());
172   filter.setComboBoxSelection((Entry)combobox.getSelectedItem());
173   return filter;
174     }
175 
176     /** Encode an expression in pseudo-regular expression into regular expression.
177      * @param raw The pseudo-regular expression <strong>String</strong> which includes several characters which differ in meaning from regular expression queries.
178      * @return A proper regular expression as a <strong>String</strong>.
179      */
180     private String encode(String raw) {
181   StringBuffer working = new StringBuffer();
182   for(int i = 0; i < raw.length(); i++) {
183       char c = raw.charAt(i);
184       switch(c) {
185       case '.':
186     working.append("\\.");
187     break;
188       case '*':
189     working.append(".*");
190     break;
191       case '?':
192     working.append(".");
193     break;
194       default:
195     working.append(Character.toLowerCase(c));
196       }
197   }
198   return working.toString();
199     }
200     /** This method applies the given pattern to the tree registered as belonging to this filter.*/
201     private void setFilter(Pattern pattern) {
202   // Show busy cursor.
203   Gatherer.g_man.wait(true);
204   FileSystemModel model = (FileSystemModel) tree.getModel();
205   // Apply filter
206   if(pattern != null) {
207       model.setFilter(pattern.pattern());
208   }
209   else {
210       model.setFilter(null);
211   }
212   // Ask tree to completely refresh
213   tree.refresh(null);
214   // Restore cursor
215   Gatherer.g_man.wait(false);
216     }
217 
218     /** Listens for changes in the combobox as when one is detected attempts to compile a regular expression from whatever text was entered. If successful, or if the item chosen was a predefined filter, it then applies the filter to the target tree. */
219     private class ComboBoxListener
220   implements ActionListener {
221   /** Called when a new item is selected from the filter combobox, we treat the new entry as a pseudo-regular expression, compile it and then apply it to the tree.
222    * @param event An <strong>ActionEvent</strong> containing more information about the change performed.
223    * @see org.greenstone.gatherer.gui.Filter.Entry
224    */
225   public void actionPerformed(ActionEvent event) {
226       try {
227     Object temp = combobox.getSelectedItem();
228     Entry entry = null;
229     if(temp instanceof String) {
230         String temp_str = (String) temp;
231         ///ystem.err.println("Filter = " + temp_str);
232 
233         // Ignore any string which matches a predefined filter
234         if(temp_str.equals(Dictionary.get("Filter.All_Files"))) {
235         }
236         // HTM & HTML
237         else if(temp_str.equals(Dictionary.get("Filter.0"))) {
238         }
239         // XML
240         else if(temp_str.equals(Dictionary.get("Filter.1"))) {
241         }
242         // Text files
243         else if(temp_str.equals(Dictionary.get("Filter.2"))) {
244         }
245         // Images
246         else if(temp_str.equals(Dictionary.get("Filter.3"))) {
247         }
248         else {
249       // Make sure the filter isn't already in the list
250       boolean already_exists = false;
251       for (int i = 0; i < combobox.getItemCount(); i++) {
252           if (temp_str.equals(combobox.getItemAt(i).toString())) {
253         already_exists = true;
254         entry = (Entry) combobox.getItemAt(i);
255         break;
256           }
257       }
258 
259       if (already_exists == false) {
260           entry = new Entry(temp_str, Pattern.compile(encode(temp_str)));
261           int position = combobox.getItemCount();
262           combobox.insertItemAt(entry, position);
263           combobox.setSelectedIndex(position);
264       }
265         }
266     }
267     else {
268         ///ystem.err.println("Custom Filter");
269         entry = (Entry) temp;
270     }
271     if(entry != null) {
272         setFilter(entry.getPattern());
273     }
274     // Else we ignore this event as being one of the painfully erroneous events we receive because we've been silly enough to have an editable combobox.
275       }
276       catch (PatternSyntaxException error) {
277     if(first) {
278         JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("Filter.Invalid_Pattern"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
279     }
280       }
281   }
282     }
283     /** An object that holds a filter entry. This is string used for the filter pattern and, if not custom built, its name. */
284     private class Entry
285   implements Comparable {
286   /** The compiled pattern created from a regular expression. */
287   private Pattern pattern = null;
288   /** The name of this filter entry. */
289   private String name = null;
290   /** Constructor. */
291   public Entry() {
292   }
293   /** Constructor.
294    * @param name The name of this entry as a <strong>String</strong>.
295    * @param pattern The compiled regular expression as a <strong>Pattern</strong>.
296    */
297   public Entry(String name, Pattern pattern) {
298       this.name = name;
299       this.pattern = pattern;
300   }
301   /** Compare two Entrys for ordering.
302    * @param object The other Entry to compare to, as an <strong>Object</strong>.
303    * @return An <i>int</i> indicating the respective ordering, as defined in java.lang.String#compareTo
304    */
305   public int compareTo(Object object) {
306       return toString().compareTo(object.toString());
307   }
308   /** Retrieve the pattern associated with this entry.
309    * @return The <strong>Pattern</strong>.
310    */
311   public Pattern getPattern() {
312       return pattern;
313   }
314   /** Translate this entry into a textual representation.
315    * @return A <strong>String</strong> containing the representation.
316    */
317   public String toString() {
318       String result = null;
319       if (name != null) {
320     result = name;
321       }
322       else if (pattern == null) {
323     result = Dictionary.get("Filter.All_Files");
324       }
325       else {
326     result = pattern.pattern();
327       }
328       return result;
329   }
330     }
331 }