KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > core > windows > view > ui > slides > SlideBar


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.core.windows.view.ui.slides;
21
22 import java.awt.Component JavaDoc;
23 import java.awt.Dimension JavaDoc;
24 import java.awt.Insets JavaDoc;
25 import java.awt.Point JavaDoc;
26 import java.awt.Rectangle JavaDoc;
27 import java.awt.event.ActionEvent JavaDoc;
28 import java.awt.event.ActionListener JavaDoc;
29 import java.awt.event.MouseEvent JavaDoc;
30 import java.util.ArrayList JavaDoc;
31 import java.util.Arrays JavaDoc;
32 import java.util.HashSet JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.List JavaDoc;
35 import java.util.Set JavaDoc;
36 import javax.swing.Box JavaDoc;
37 import javax.swing.BoxLayout JavaDoc;
38 import javax.swing.DefaultSingleSelectionModel JavaDoc;
39 import javax.swing.JButton JavaDoc;
40 import javax.swing.JComponent JavaDoc;
41 import javax.swing.SingleSelectionModel JavaDoc;
42 import javax.swing.SwingUtilities JavaDoc;
43 import javax.swing.UIManager JavaDoc;
44 import javax.swing.border.Border JavaDoc;
45 import javax.swing.border.EmptyBorder JavaDoc;
46 import javax.swing.event.ChangeEvent JavaDoc;
47 import javax.swing.event.ChangeListener JavaDoc;
48 import javax.swing.event.ListDataEvent JavaDoc;
49 import org.netbeans.core.windows.Constants;
50 import org.netbeans.core.windows.WindowManagerImpl;
51 import org.netbeans.core.windows.view.ui.Tabbed;
52 import org.netbeans.core.windows.view.ui.tabcontrol.TabbedAdapter;
53 import org.netbeans.swing.tabcontrol.DefaultTabDataModel;
54 import org.netbeans.swing.tabcontrol.SlideBarDataModel;
55 import org.netbeans.swing.tabcontrol.SlidingButton;
56 import org.netbeans.swing.tabcontrol.TabData;
57 import org.netbeans.swing.tabcontrol.TabDataModel;
58 import org.netbeans.swing.tabcontrol.TabDisplayer;
59 import org.netbeans.swing.tabcontrol.TabbedContainer;
60 import org.netbeans.swing.tabcontrol.WinsysInfoForTabbed;
61 import org.netbeans.swing.tabcontrol.event.ComplexListDataEvent;
62 import org.netbeans.swing.tabcontrol.event.ComplexListDataListener;
63 import org.netbeans.swing.tabcontrol.event.TabActionEvent;
64 import org.openide.windows.TopComponent;
65
66 /*
67  * Swing component of slide bar.
68  * Holds and shows set of toggle slide buttons and synchronizes them with
69  * data model.
70  *
71  * All data manipulation are done indirectly through ascoiated models,
72  * Swing AWT hierarchy is just synchronized.
73  *
74  * @author Dafe Simonek
75  */

76 public final class SlideBar extends Box JavaDoc implements ComplexListDataListener,
77     SlideBarController, Tabbed.Accessor, WinsysInfoForTabbed, ChangeListener JavaDoc {
78     
79     /** Command indicating request for slide in (appear) of sliding component */
80     public static final String JavaDoc COMMAND_SLIDE_IN = "slideIn"; //NOI18N
81

82     /** Command indicating request for slide out (hide) of sliding component */
83     public static final String JavaDoc COMMAND_SLIDE_OUT = "slideOut"; //NOI18N
84

85     public static final String JavaDoc COMMAND_SLIDE_RESIZE = "slideResize"; //NOI18N
86

87     /** Action command indicating that a popup menu should be shown */
88     public static final String JavaDoc COMMAND_POPUP_REQUEST = "popup"; //NOI18N
89

90     /** Action command indicating that component is going from auto-hide state to regular */
91     public static final String JavaDoc COMMAND_DISABLE_AUTO_HIDE = "disableAutoHide"; //NOI18N
92

93     /** Action command indicating that component is going from regular to maximized size and vice versa */
94     public static final String JavaDoc COMMAND_MAXIMIZE = "slideMaximize"; //NOI18N
95

96     /** Asociation with Tabbed implementation */
97     private final TabbedSlideAdapter tabbed;
98     /** Holds all data of slide bar */
99     private final SlideBarDataModel dataModel;
100     /** Selection info */
101     private final SingleSelectionModel JavaDoc selModel;
102     /** listener for mouse actions and moves, which trigger slide operations */
103     private SlideGestureRecognizer gestureRecognizer;
104     /** list of sliding buttons */
105     private List JavaDoc<SlidingButton> buttons;
106     /** operation handler */
107     private CommandManager commandMgr;
108     /** true when this slide bar is active in winsys, false otherwise */
109     private boolean active = false;
110     
111     /** Creates a new instance of SlideBarContainer with specified orientation.
112      * See SlideBarDataModel for possible orientation values.
113      */

114     public SlideBar(TabbedSlideAdapter tabbed, SlideBarDataModel dataModel, SingleSelectionModel JavaDoc selModel) {
115         super(dataModel.getOrientation() == SlideBarDataModel.SOUTH
116                 ? BoxLayout.X_AXIS : BoxLayout.Y_AXIS);
117         this.tabbed = tabbed;
118         this.dataModel = dataModel;
119         this.selModel = selModel;
120         commandMgr = new CommandManager(this);
121         gestureRecognizer = new SlideGestureRecognizer(this, commandMgr.getResizer());
122         buttons = new ArrayList JavaDoc<SlidingButton>(5);
123         
124         syncWithModel();
125         
126         dataModel.addComplexListDataListener(this);
127         selModel.addChangeListener(this);
128     }
129     
130     public SlideBarDataModel getModel() {
131         return dataModel;
132     }
133     
134     public SingleSelectionModel JavaDoc getSelectionModel () {
135         return selModel;
136     }
137     
138     /***** reactions to changes in data model, synchronizes AWT hierarchy and display ***/
139     
140     public void intervalAdded(ListDataEvent JavaDoc e) {
141         assert SwingUtilities.isEventDispatchThread();
142         
143         int first = e.getIndex0();
144         int last = e.getIndex1();
145         SlideBarDataModel data = (SlideBarDataModel)e.getSource();
146         SlidingButton curButton;
147         for (int i = first; i <= last; i++) {
148             curButton = new SlidingButton(data.getTab(i), data.getOrientation());
149             gestureRecognizer.attachButton(curButton);
150             buttons.add(i, curButton);
151             add(curButton, i * 2);
152             add(createStrut(), i * 2 + 1);
153             revalidate();
154         }
155     }
156     
157     public void intervalRemoved(ListDataEvent JavaDoc e) {
158         assert SwingUtilities.isEventDispatchThread();
159         
160         int first = e.getIndex0();
161         int last = e.getIndex1();
162         SlideBarDataModel data = (SlideBarDataModel)e.getSource();
163         SlidingButton curButton = null;
164         for (int i = last; i >= first; i--) {
165             gestureRecognizer.detachButton((SlidingButton)buttons.get(i));
166             buttons.remove(i);
167             // have to remove also strut (space) component
168
remove(i * 2 + 1);
169             remove(i * 2);
170         }
171     }
172     
173     public void contentsChanged(ListDataEvent JavaDoc e) {
174         syncWithModel();
175     }
176     
177     public void indicesAdded(ComplexListDataEvent e) {
178         syncWithModel();
179     }
180     
181     public void indicesChanged(ComplexListDataEvent e) {
182         syncWithModel();
183     }
184     
185     public void indicesRemoved(ComplexListDataEvent e) {
186         syncWithModel();
187     }
188
189     /** Finds button which contains given point and returns button's index
190      * valid in asociated dataModel. Or returns -1 if no button contains
191      * given point
192      */

193     public int tabForCoordinate(int x, int y) {
194         Rectangle JavaDoc curBounds = new Rectangle JavaDoc();
195         int index = 0;
196         for (Iterator JavaDoc iter = buttons.iterator(); iter.hasNext(); index++) {
197             ((Component JavaDoc)iter.next()).getBounds(curBounds);
198             if (curBounds.contains(x, y)) {
199                 return index;
200             }
201         }
202         return -1;
203     }
204     
205     int nextTabForCoordinate(int x, int y) {
206         Rectangle JavaDoc curBounds = new Rectangle JavaDoc();
207         int index = 0;
208         Iterator JavaDoc iter = buttons.iterator();
209         while (iter.hasNext()) {
210             Component JavaDoc comp = (Component JavaDoc)iter.next();
211             comp.getBounds(curBounds);
212             if (dataModel.getOrientation() == SlideBarDataModel.SOUTH) {
213                 if (curBounds.x + (curBounds.width/2) < x) {
214                     index = index + 1;
215                     continue;
216                 }
217             } else {
218                 if (curBounds.y + (curBounds.height/2) < y) {
219                     index = index + 1;
220                     continue;
221                 }
222             }
223             return index;
224         }
225         return index;
226     }
227     
228     
229     /** Implementation of ChangeListener, reacts to selection changes
230      * and assures that currently selected component is slided in
231      */

232     public void stateChanged(ChangeEvent JavaDoc e) {
233         int selIndex = selModel.getSelectedIndex();
234         
235         // notify winsys about selection change
236
tabbed.postSelectionEvent();
237         // a check to prevent NPE as described in #43605, dafe - is this correct or rather a hack? mkleint
238
if (isDisplayable() && isVisible()) {
239             // slide in or out
240
if (selIndex != -1) {
241                 commandMgr.slideIn(selIndex);
242             } else {
243                 commandMgr.slideOut(true, true);
244             }
245         }
246     }
247     
248     
249     /********** implementation of SlideBarController *****************/
250     
251     public void userToggledAutoHide(int tabIndex, boolean enabled) {
252         commandMgr.slideIntoDesktop(tabIndex, true);
253     }
254     
255     public void userTriggeredPopup(MouseEvent JavaDoc mouseEvent, Component JavaDoc clickedButton) {
256         int index = getButtonIndex(clickedButton);
257         commandMgr.showPopup(mouseEvent, index);
258     }
259     
260     private SlidingButton buttonFor (TopComponent tc) {
261         int idx = 0;
262         for (Iterator JavaDoc i=dataModel.getTabs().iterator(); i.hasNext();) {
263             TabData td = (TabData) i.next();
264             if (td.getComponent() == tc) {
265                 break;
266             }
267             if (!i.hasNext()) {
268                 idx = -1;
269             } else {
270                 idx++;
271             }
272         }
273         if (idx >= 0 && idx < dataModel.size()) {
274             return getButton(idx);
275         } else {
276             return null;
277         }
278     }
279     
280     public void setBlinking (TopComponent tc, boolean val) {
281         SlidingButton button = buttonFor (tc);
282         if (button != null) {
283             button.setBlinking(val);
284         }
285     }
286
287     /** Triggers slide operation by changing selected index */
288     public void userClickedSlidingButton(Component JavaDoc clickedButton) {
289         int index = getButtonIndex(clickedButton);
290         SlidingButton button = (SlidingButton) buttons.get(index);
291         button.setBlinking(false);
292         
293         if (index != selModel.getSelectedIndex() || !isActive()) {
294             TopComponent tc = (TopComponent)dataModel.getTab(index).getComponent();
295             if (tc != null) {
296                 tc.requestActive();
297             }
298         } else {
299             selModel.setSelectedIndex(-1);
300         }
301     }
302
303     /** Request for automatic slide in from gesture recognizer */
304     public boolean userTriggeredAutoSlideIn(Component JavaDoc sourceButton) {
305         int index = getButtonIndex(sourceButton);
306         if (index < 0) {
307             return false;
308         }
309         SlidingButton button = (SlidingButton) buttons.get(index);
310         button.setBlinking(false);
311         TopComponent tc = (TopComponent)dataModel.getTab(index).getComponent();
312         if (tc == null) {
313             return false;
314         }
315         tc.requestVisible();
316         return true;
317     }
318     
319     /** Request for automatic slide out from gesture recognizer */
320     public void userTriggeredAutoSlideOut() {
321         selModel.setSelectedIndex(-1);
322     }
323     
324     public Rectangle JavaDoc getTabBounds(int tabIndex) {
325         Component JavaDoc button = getButton(tabIndex);
326         if (button == null) {
327             return null;
328         }
329         Insets JavaDoc insets = getInsets();
330         Point JavaDoc leftTop = new Point JavaDoc(insets.left, insets.top);
331         
332         Dimension JavaDoc strutPrefSize = createStrut().getPreferredSize();
333         if (dataModel.getOrientation() == SlideBarDataModel.SOUTH) {
334             // horizontal layout
335
for (int i = 0; i < tabIndex; i++) {
336                 leftTop.x += getButton(i).getPreferredSize().width;
337                 leftTop.x += strutPrefSize.width;
338             }
339         } else {
340             // vertical layout
341
for (int i = 0; i < tabIndex; i++) {
342                 leftTop.y += getButton(i).getPreferredSize().height;
343                 leftTop.y += strutPrefSize.height;
344             }
345         }
346         return new Rectangle JavaDoc(leftTop, button.getPreferredSize());
347     }
348     
349     /********* implementation of Tabbed.Accessor **************/
350     
351     public Tabbed getTabbed () {
352         return tabbed;
353     }
354     
355     /********* implementation of WinsysInfoForTabbed **************/
356     
357     public Object JavaDoc getOrientation(Component JavaDoc comp) {
358         if (WindowManagerImpl.getInstance().getEditorAreaState() != Constants.EDITOR_AREA_JOINED) {
359             return TabDisplayer.ORIENTATION_INVISIBLE;
360         }
361         return TabDisplayer.ORIENTATION_CENTER;
362     }
363     
364     public boolean inMaximizedMode(Component JavaDoc comp) {
365         return TabbedAdapter.isInMaximizedMode(comp);
366     }
367     
368     
369     /*************** non public stuff **************************/
370     
371     /* #return Component that is slided into desktop or null if no component is
372      * slided currently.
373      */

374     Component JavaDoc getSlidedComp() {
375         return commandMgr.getSlidedComp();
376     }
377     
378     void setActive(boolean active) {
379         this.active = active;
380         commandMgr.setActive(active);
381     }
382     
383     boolean isActive() {
384         return active;
385     }
386     
387     boolean isHoveringAllowed() {
388         return !isActive() || !commandMgr.isCompSlided();
389     }
390     
391     int getButtonIndex(Component JavaDoc button) {
392         return buttons.indexOf(button);
393     }
394     
395     SlidingButton getButton(int index) {
396         return (SlidingButton)buttons.get(index);
397     }
398     
399     /** @return true if slide bar contains given component, false otherwise */
400     boolean containsComp(Component JavaDoc comp) {
401         List JavaDoc tabs = getModel().getTabs();
402         TabData curTab = null;
403         for (Iterator JavaDoc iter = tabs.iterator(); iter.hasNext(); ) {
404             curTab = (TabData)iter.next();
405             if (comp.equals(curTab.getComponent())) {
406                 return true;
407             }
408         }
409         return false;
410     }
411     
412     private Component JavaDoc createStrut () {
413         return dataModel.getOrientation() == SlideBarDataModel.SOUTH
414             ? createHorizontalStrut(5) : createVerticalStrut(5);
415     }
416     
417     private void syncWithModel () {
418         assert SwingUtilities.isEventDispatchThread();
419         Set JavaDoc<TabData> blinks = null;
420         for (SlidingButton curr: buttons) {
421             if (curr.isBlinking()) {
422                 if (blinks == null) {
423                     blinks = new HashSet JavaDoc<TabData>();
424                 }
425                 blinks.add (curr.getData());
426             }
427             gestureRecognizer.detachButton(curr);
428         }
429         removeAll();
430         buttons.clear();
431         
432         List JavaDoc<TabData> dataList = dataModel.getTabs();
433         SlidingButton curButton;
434         for (Iterator JavaDoc iter = dataList.iterator(); iter.hasNext(); ) {
435             TabData td = (TabData) iter.next();
436             curButton = new SlidingButton(td, dataModel.getOrientation());
437             if (blinks != null && blinks.contains(td)) {
438                 curButton.setBlinking(true);
439             }
440             gestureRecognizer.attachButton(curButton);
441             buttons.add(curButton);
442             add(curButton);
443             add(createStrut());
444         }
445
446         commandMgr.syncWithModel();
447         // #46488 - add(...) is sometimes not enough for proper repaint, god knows why
448
revalidate();
449         //#47227 - repaint the bar when removing component from bar.
450
//#48318 - repaint when changing name -> can change the width of buttons.
451
repaint();
452     }
453     
454 }
455
456
457     /********* Swing standard handling mechanism for asociated UI class - will
458       see if we need our own UI class or not */

459     
460     /** String ID of UI class for slide bar used in UIManager */
461     //private static final String uiClassID = "SlideBarUI";
462

463     /**
464      * Returns the tool bar's current UI.
465      * @see #setUI
466      */

467     /*public SlideBarUI getUI() {
468         return (SlideBarUI)ui;
469     }*
470     
471     /**
472      * Sets the L&F object that renders this component.
473      */

474     /*public void setUI(SlideBarUI ui) {
475         super.setUI(ui);
476     }*/

477     
478     /**
479      * Notification from the <code>UIFactory</code> that the L&F has changed.
480      * Called to replace the UI with the latest version from the
481      * <code>UIFactory</code>.
482      *
483      * @see JComponent#updateUI
484      */

485     /*public void updateUI() {
486         setUI((SlideBarUI)UIManager.getUI(this));
487         invalidate();
488     }*/

489
490     /**
491      * Returns the name of the L&F class that renders this component.
492      */

493     /*public String getUIClassID() {
494         return uiClassID;
495     }*/

496
Popular Tags