001    /*
002     * Copyright 2002-2007 the original author or authors.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     * 
008     * http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package org.springframework.richclient.util;
017    
018    import java.awt.Component;
019    
020    import javax.swing.JMenu;
021    import javax.swing.JMenuBar;
022    import javax.swing.JPopupMenu;
023    import javax.swing.JSeparator;
024    import javax.swing.JToolBar;
025    
026    /**
027     * Utils class for consolidating separators on toolbars, popupmenus and menus.
028     * 
029     * @author Benoit Xhenseval
030     * @author Peter De Bruycker
031     */
032    public class SeparatorUtils {
033    
034            private SeparatorUtils() {
035                    // static utils only
036            }
037    
038            /**
039             * Consolidates separators in a toolbar:
040             * <ul>
041             * <li>subsequent separators will be collapsed to one separator</li>
042             * <li>if the first visible item of a menu is a separator, it will be made
043             * invisible</li>
044             * <li>if the last visible item of a menu is a separator, it will be made
045             * invisible</li>
046             * </ul>
047             * @param menu the menu (cannot be null)
048             */
049            public static void consolidateSeparators(JToolBar toolBar) {
050                    Assert.notNull(toolBar, "toolBar cannot be null");
051    
052                    consolidateSeparators(toolBar.getComponents());
053            }
054    
055            /**
056             * Consolidates separators in a popupmenu:
057             * <ul>
058             * <li>subsequent separators will be collapsed to one separator</li>
059             * <li>if the first visible item of a menu is a separator, it will be made
060             * invisible</li>
061             * <li>if the last visible item of a menu is a separator, it will be made
062             * invisible</li>
063             * </ul>
064             * @param menu the menu (cannot be null)
065             */
066            public static void consolidateSeparators(JPopupMenu popupMenu) {
067                    Assert.notNull(popupMenu, "popupMenu cannot be null");
068    
069                    consolidateSeparators(popupMenu.getComponents());
070            }
071    
072            private static void consolidateSeparators(Component[] menuComponents) {
073                    Assert.notNull(menuComponents, "menuComponents cannot be null");
074    
075                    Component previousVisibleComponent = null;
076                    boolean everythingInvisibleSoFar = true;
077    
078                    for (int i = 0; i < menuComponents.length; i++) {
079                            Component menuComponent = menuComponents[i];
080    
081                            // reset all separators
082                            if (menuComponent instanceof JSeparator) {
083                                    menuComponent.setVisible(true);
084                            }
085    
086                            // Separator should be invisible if
087                            // - previous visible item one is a separator
088                            // - it is the first one visible item (ie everything invisible
089                            // before)
090                            if (menuComponent instanceof JSeparator && everythingInvisibleSoFar) {
091                                    menuComponent.setVisible(false);
092                            }
093                            else if (menuComponent instanceof JSeparator && previousVisibleComponent instanceof JSeparator) {
094                                    previousVisibleComponent.setVisible(false);
095                            }
096    
097                            if (menuComponent instanceof JSeparator) {
098                                    previousVisibleComponent = menuComponent;
099                            }
100                            else if (menuComponent.isVisible()) {
101                                    everythingInvisibleSoFar = false;
102                                    previousVisibleComponent = menuComponent;
103                            }
104    
105                            if (menuComponent instanceof JMenu) {
106                                    consolidateSeparators((JMenu) menuComponent);
107                            }
108                    }
109    
110                    // and if the last item on the menu is a separator -> make it invisible.
111                    if (previousVisibleComponent instanceof JSeparator) {
112                            previousVisibleComponent.setVisible(false);
113                    }
114            }
115    
116            /**
117             * Consolidates separators in a menu:
118             * <ul>
119             * <li>subsequent separators will be collapsed to one separator</li>
120             * <li>if the first visible item of a menu is a separator, it will be made
121             * invisible</li>
122             * <li>if the last visible item of a menu is a separator, it will be made
123             * invisible</li>
124             * </ul>
125             * @param menu the menu (cannot be null)
126             */
127            public static void consolidateSeparators(JMenu menu) {
128                    Assert.notNull(menu, "menu cannot be null");
129    
130                    Component previousVisibleComponent = null;
131                    boolean everythingInvisibleSoFar = true;
132    
133                    for (int j = 0; j < menu.getMenuComponentCount(); j++) {
134                            Component menuComponent = menu.getMenuComponent(j);
135    
136                            // reset all separators
137                            if (menuComponent instanceof JSeparator) {
138                                    menuComponent.setVisible(true);
139                            }
140    
141                            // Separator should be invisible if
142                            // - previous visible item one is a separator
143                            // - it is the first one visible item (ie everything invisible
144                            // before)
145                            if (menuComponent instanceof JSeparator && everythingInvisibleSoFar) {
146                                    menuComponent.setVisible(false);
147                            }
148                            else if (menuComponent instanceof JSeparator && previousVisibleComponent instanceof JSeparator) {
149                                    previousVisibleComponent.setVisible(false);
150                            }
151    
152                            if (menuComponent instanceof JSeparator) {
153                                    previousVisibleComponent = menuComponent;
154                            }
155                            else if (menuComponent.isVisible()) {
156                                    everythingInvisibleSoFar = false;
157                                    previousVisibleComponent = menuComponent;
158                            }
159    
160                            if (menuComponent instanceof JMenu) {
161                                    consolidateSeparators((JMenu) menuComponent);
162                            }
163                    }
164    
165                    // and if the last item on the menu is a separator -> make it invisible.
166                    if (previousVisibleComponent instanceof JSeparator) {
167                            previousVisibleComponent.setVisible(false);
168                    }
169            }
170    
171            /**
172             * Consolidates separators in a menubar. This essentialy calls
173             * {@link #consolidateSeparators(JMenu)} for each menu in the menubar.
174             * @param menuBar the menu bar (cannot be null)
175             * @see #consolidateSeparators(JMenu)
176             */
177            public static void consolidateSeparators(JMenuBar menuBar) {
178                    Assert.notNull(menuBar, "menu bar cannot be null");
179    
180                    for (int i = 0; i < menuBar.getMenuCount(); i++) {
181                            consolidateSeparators(menuBar.getMenu(i));
182                    }
183            }
184    }