KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > navigation > base > 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.java.navigation.base;
21
22 import java.awt.Dimension JavaDoc;
23 import java.awt.Insets JavaDoc;
24 import java.awt.event.ActionEvent JavaDoc;
25 import java.awt.event.ActionListener JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.Map JavaDoc;
30 import javax.swing.Box JavaDoc;
31 import javax.swing.BoxLayout JavaDoc;
32 import javax.swing.Icon JavaDoc;
33 import javax.swing.JComponent JavaDoc;
34 import javax.swing.JToggleButton JavaDoc;
35 import javax.swing.JToolBar JavaDoc;
36 import javax.swing.SwingUtilities JavaDoc;
37 import javax.swing.border.EmptyBorder JavaDoc;
38 import javax.swing.event.ChangeEvent JavaDoc;
39
40 /** Handles creation and manipulation with boolean state filters.
41  *
42  * @author Dafe Simomek
43  */

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

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

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

84     public interface FilterChangeListener {
85         /** Called whenever some changes in state of filters contained in
86          * filters panel is triggered
87          */

88         public void filterStateChanged(ChangeEvent JavaDoc e);
89         
90     } // end of FilterChangeListener
91

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

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

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

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

285 }
286
Popular Tags