KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > text > navigator > FiltersManager


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.xml.text.navigator;
21
22 import java.awt.Component JavaDoc;
23 import java.awt.Dimension JavaDoc;
24 import java.awt.Insets JavaDoc;
25 import java.awt.event.ActionEvent JavaDoc;
26 import java.awt.event.ActionListener JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Map JavaDoc;
32 import javax.swing.Box JavaDoc;
33 import javax.swing.BoxLayout JavaDoc;
34 import javax.swing.Icon JavaDoc;
35 import javax.swing.JComponent JavaDoc;
36 import javax.swing.JToggleButton JavaDoc;
37 import javax.swing.JToolBar JavaDoc;
38 import javax.swing.SwingUtilities JavaDoc;
39 import javax.swing.border.EmptyBorder JavaDoc;
40 import javax.swing.event.ChangeEvent JavaDoc;
41 import javax.swing.event.ChangeListener JavaDoc;
42
43 /** Handles creation and manipulation with boolean state filters.
44  *
45  * @author Dafe Simomek
46  */

47 public final class FiltersManager {
48     
49     private FiltersComponent comp;
50     
51     static FiltersManager create (FiltersDescription descr) {
52         return new FiltersManager(descr);
53     }
54     
55     /** Returns true when given filter is selected, false otherwise.
56      * Note that this method is thread safe, can be called from any thread
57      * (and usually will, as clients will call this from loadContent naturally)
58      */

59     public boolean isSelected (String JavaDoc filterName) {
60         return comp.isSelected(filterName);
61     }
62     
63     /** Sets boolean value of filter with given name. True means filter is
64      * selected (enabled), false otherwise. Note, must be called from AWT thread.
65      */

66     public void setSelected (String JavaDoc filterName, boolean value) {
67         comp.setFilterSelected(filterName, value);
68     }
69
70     /** @return component instance visually representing filters */
71     public JComponent JavaDoc getComponent () {
72         return comp;
73     }
74     
75     /** @return Filters description */
76     public FiltersDescription getDescription () {
77         return comp.getDescription();
78     }
79
80     /** Assigns listener for listening to filter changes */
81     public void hookChangeListener (FilterChangeListener l) {
82         comp.hookFilterChangeListener(l);
83     }
84     
85     /** Interface for listening to changes of filter states contained in FIltersPanel
86      */

87     public interface FilterChangeListener {
88         /** Called whenever some changes in state of filters contained in
89          * filters panel is triggered
90          */

91         public void filterStateChanged(ChangeEvent JavaDoc e);
92         
93     } // end of FilterChangeListener
94

95
96     /** Private, creation managed by factory method 'create' */
97     private FiltersManager (FiltersDescription descr) {
98         comp = new FiltersComponent(descr);
99     }
100     
101     /** Swing component representing filters in panel filled with toggle buttons.
102      * Provides thread safe access to the states of filters by copying states
103      * into private map, properly sync'ed.
104      */

105     private class FiltersComponent extends Box JavaDoc implements ActionListener JavaDoc {
106         
107         /** list of <JToggleButton> visually representing filters */
108         private List JavaDoc toggles;
109         /** description of filters */
110         private final FiltersDescription filtersDesc;
111  
112         /** lock for listener */
113         private Object JavaDoc L_LOCK = new Object JavaDoc();
114         /** listener */
115         private FilterChangeListener clientL;
116
117         /** lock for map of filter states */
118         private Object JavaDoc STATES_LOCK = new Object JavaDoc();
119         /** copy of filter states for accessing outside AWT */
120         private Map JavaDoc filterStates;
121
122         /** Returns selected state of given filter, thread safe.
123          */

124         public boolean isSelected (String JavaDoc filterName) {
125             Boolean JavaDoc result;
126             synchronized (STATES_LOCK) {
127                 if (filterStates == null) {
128                     // Swing toggles not initialized yet
129
int index = filterIndexForName(filterName);
130                     if (index < 0) {
131                         return false;
132                     } else {
133                         return filtersDesc.isSelected(index);
134                     }
135                 }
136                 result = (Boolean JavaDoc)filterStates.get(filterName);
137             }
138             
139             if (result == null) {
140                 throw new IllegalArgumentException JavaDoc("Filter " + filterName + " not found.");
141             }
142             return result.booleanValue();
143         }
144         
145         /** Sets filter value, AWT only */
146         public void setFilterSelected (String JavaDoc filterName, boolean value) {
147             assert SwingUtilities.isEventDispatchThread();
148             
149             int index = filterIndexForName(filterName);
150             if (index < 0) {
151                 throw new IllegalArgumentException JavaDoc("Filter " + filterName + " not found.");
152             }
153             // update both swing control and states map
154
((JToggleButton JavaDoc)toggles.get(index)).setSelected(value);
155             synchronized (STATES_LOCK) {
156                 filterStates.put(filterName, Boolean.valueOf(value));
157             }
158             // notify
159
fireChange();
160         }
161         
162         public void hookFilterChangeListener (FilterChangeListener l) {
163             synchronized (L_LOCK) {
164                 clientL = l;
165             }
166         }
167         
168         public FiltersDescription getDescription () {
169             return filtersDesc;
170         }
171     
172         /** Not public, instances created using factory method createPanel */
173         FiltersComponent(FiltersDescription descr) {
174             super(BoxLayout.X_AXIS);
175             this.filtersDesc = descr;
176             // always create swing content in AWT thread
177
if (!SwingUtilities.isEventDispatchThread()) {
178                 SwingUtilities.invokeLater(new Runnable JavaDoc () {
179                     public void run () {
180                         initPanel();
181                     }
182                 });
183             } else {
184                 initPanel();
185             }
186         }
187
188         /** Called only from AWT */
189         private void initPanel () {
190             setBorder(new EmptyBorder JavaDoc(1, 2, 3, 5));
191
192             // configure toolbar
193
JToolBar JavaDoc toolbar = new JToolBar JavaDoc(JToolBar.HORIZONTAL);
194             toolbar.setFloatable(false);
195             toolbar.setRollover(true);
196             toolbar.setBorderPainted(false);
197             // create toggle buttons
198
int filterCount = filtersDesc.getFilterCount();
199             toggles = new ArrayList JavaDoc(filterCount);
200             JToggleButton JavaDoc toggleButton = null;
201             
202             Map JavaDoc fStates = new HashMap JavaDoc(filterCount * 2);
203
204             for (int i = 0; i < filterCount; i++) {
205                 toggleButton = createToggle(fStates, i);
206                 toggles.add(toggleButton);
207             }
208             
209             // add toggle buttons
210
JToggleButton JavaDoc curToggle;
211             Dimension JavaDoc space = new Dimension JavaDoc(3, 0);
212             for (int i = 0; i < toggles.size(); i++) {
213                 curToggle = (JToggleButton JavaDoc)toggles.get(i);
214                 curToggle.addActionListener(this);
215                 toolbar.add(curToggle);
216                 if (i != toggles.size() - 1) {
217                     toolbar.addSeparator(space);
218                 }
219             }
220             
221             add(toolbar);
222             
223             // initialize member states map
224
synchronized (STATES_LOCK) {
225                 filterStates = fStates;
226             }
227         }
228         
229         private JToggleButton JavaDoc createToggle (Map JavaDoc fStates, int index) {
230             boolean isSelected = filtersDesc.isSelected(index);
231             Icon JavaDoc icon = filtersDesc.getSelectedIcon(index);
232             // ensure small size, just for the icon
233
JToggleButton JavaDoc result = new JToggleButton JavaDoc(icon, isSelected);
234             Dimension JavaDoc size = new Dimension JavaDoc(icon.getIconWidth() + 6, icon.getIconHeight() + 4);
235             result.setPreferredSize(size);
236             result.setMargin(new Insets JavaDoc(2,3,2,3));
237             result.setToolTipText(filtersDesc.getTooltip(index));
238             
239             fStates.put(filtersDesc.getName(index), Boolean.valueOf(isSelected));
240             
241             return result;
242         }
243
244         /** Finds and returns index of filter with given name or -1 if no
245          * such filter exists.
246          */

247         private int filterIndexForName (String JavaDoc filterName) {
248             int filterCount = filtersDesc.getFilterCount();
249             String JavaDoc curName;
250             for (int i = 0; i < filterCount; i++) {
251                 curName = filtersDesc.getName(i);
252                 if (filterName.equals(curName)) {
253                     return i;
254                 }
255             }
256             return -1;
257         }
258
259         /** Reactions to toggle button click, */
260         public void actionPerformed(ActionEvent JavaDoc e) {
261             // copy changed state first
262
JToggleButton JavaDoc toggle = (JToggleButton JavaDoc)e.getSource();
263             int index = toggles.indexOf(e.getSource());
264             synchronized (STATES_LOCK) {
265                 filterStates.put(filtersDesc.getName(index),
266                                 Boolean.valueOf(toggle.isSelected()));
267             }
268             // notify
269
fireChange();
270         }
271         
272         private void fireChange () {
273             FilterChangeListener lCopy;
274             synchronized (L_LOCK) {
275                 // no listener = no notification
276
if (clientL == null) {
277                     return;
278                 }
279                 lCopy = clientL;
280             }
281             
282             // notify listener
283
lCopy.filterStateChanged(new ChangeEvent JavaDoc(FiltersManager.this));
284         }
285     
286     } // end of FiltersComponent
287

288 }
289
Popular Tags