KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > retouche > 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.retouche.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 /**
41  * This file is originally from Retouche, the Java Support
42  * infrastructure in NetBeans. I have modified the file as little
43  * as possible to make merging Retouche fixes back as simple as
44  * possible.
45  * <p>
46  * Handles creation and manipulation with boolean state filters.
47  *
48  * @author Dafe Simomek
49  */

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

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

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

90     public interface FilterChangeListener {
91         /** Called whenever some changes in state of filters contained in
92          * filters panel is triggered
93          */

94         public void filterStateChanged(ChangeEvent JavaDoc e);
95         
96     } // end of FilterChangeListener
97

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

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

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

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

291 }
292
Popular Tags