001    package sale;
002    
003    import java.util.*;
004    
005    import javax.swing.*;
006    import java.awt.*;
007    
008    /**
009     * A MenuSheet consisting of {@link MenuSheetObject MenuSheetObjects}.
010     *
011     * <p>MenuSheets represent menus, abstracting from the form they are being displayed in. A MenuSheet could be
012     * displayed as a JMenuBar as well as a JMenu or JPopUpMenu. Independently of this it will always behave in
013     * the same way from the point of view of the applicion developer.</p>
014     *
015     * @author Steffen Zschaler
016     * @version 2.0 20/05/1999
017     * @since v1.0
018     */
019    public class MenuSheet extends MenuSheetObject {
020    
021        /**
022         * The JMenu peer, if any.
023         */
024        protected transient JMenu m_jmPeer = null;
025    
026        /**
027         * The JMenuBar peer, if any.
028         */
029        protected transient JMenuBar m_jmbBarPeer = null;
030    
031        /**
032         * The monitor used to synchronize access to the peers.
033         */
034        private transient Object m_oPeerLock;
035        /**
036         * Return the monitor used to synchronized access to the peers.
037         *
038         * @override Never
039         */
040        protected final Object getPeerLock() {
041            if (m_oPeerLock == null) {
042                m_oPeerLock = new Object();
043            }
044    
045            return m_oPeerLock;
046        }
047    
048        /**
049         * The MenuSheet that has been merged into this one, if any.
050         *
051         * @serial
052         */
053        protected MenuSheet m_msMerged = null;
054    
055        /**
056         * The tag before which the merged menu was inserted.
057         *
058         * @serial
059         */
060        protected String m_sMergedBefore = null;
061    
062        /**
063         * The peer index at which the merged menu was inserted.
064         *
065         * @serial
066         */
067        protected int m_nMergedAt = -1;
068    
069        /**
070         * The MenuSheet into which this MenuSheet was merged, if any.
071         *
072         * @serial
073         */
074        protected MenuSheet m_msMergeParent = null;
075    
076        /**
077         * The items of this MenuSheet.
078         *
079         * @serial
080         */
081        protected LinkedList m_lmsoItems;
082    
083        /**
084         * The Images associated with the icons of this MenuSheet( [0]:DefaultImage, [1]:PressedImage,
085         * [2]:DisabledImage, [3]:PressedDiabledImage ).
086         *
087         * @serial
088         */
089        protected ImageIcon m_aiImages[] = null;
090    
091        /**
092         * The Mnemonic of this MenuSheet.
093         *
094         * @serial
095         */
096        protected char m_cMnemonic;
097    
098        /**
099         * The ToolTip of this MenuSheet.
100         *
101         * @serial
102         */
103        protected String m_sToolTip = "";
104    
105        private void writeObject(java.io.ObjectOutputStream oos) throws java.io.IOException {
106            util.Debug.print("Starting to write menu sheet: \"" + getCaption() + "\" <" + getTag() + ">", -1);
107    
108            oos.defaultWriteObject();
109    
110            util.Debug.print("Done writing menu sheet: \"" + getCaption() + "\" <" + getTag() + ">", -1);
111        }
112    
113        // Helpmethod for setting an ImageIcon
114        private void setIcon(ImageIcon iiImageIcon, int nIndex) {
115            if (m_aiImages == null) {
116                m_aiImages = new ImageIcon[4];
117    
118            }
119            m_aiImages[nIndex] = iiImageIcon;
120    
121            synchronized (getPeerLock()) {
122                if (m_jmPeer != null) {
123                    switch (nIndex) {
124                        case DEFAULT_IMAGE:
125                            m_jmPeer.setIcon(iiImageIcon);
126                            break;
127                        case SELECTED_IMAGE:
128                            m_jmPeer.setSelectedIcon(iiImageIcon);
129                            break;
130                        case DISABLED_IMAGE:
131                            m_jmPeer.setDisabledIcon(iiImageIcon);
132                            break;
133                        case DISABLED_SELECTED_IMAGE:
134                            m_jmPeer.setDisabledSelectedIcon(iiImageIcon);
135                            break;
136                    }
137    
138                    m_jmPeer.validate();
139                }
140            }
141        }
142    
143        /**
144         * Creates a new MenuSheet with caption, tag and mnemonic.
145         *
146         * @param sCaption the caption of the new MenuSheet.
147         * @param sTag the tag of the new MenuSheet. If <code>null</code> a default tag will be created.
148         * @param cMnemonic the mnemonic of the new MenuSheet.
149         */
150        public MenuSheet(String sCaption, String sTag, char cMnemonic) {
151            super(sCaption, sTag);
152            m_cMnemonic = cMnemonic;
153    
154            m_lmsoItems = new LinkedList();
155        }
156    
157        /**
158         * Creates a new MenuSheet with caption and tag.
159         *
160         * @param sCaption the caption of the new MenuSheet.
161         * @param sTag the tag of the new MenuSheet. If <code>null</code> a default tag will be created.
162         */
163        public MenuSheet(String sCaption, String sTag) {
164            this(sCaption, sTag, '\0');
165    
166            m_lmsoItems = new LinkedList();
167        }
168    
169        /**
170         * Creates a new MenuSheet with caption and a default tag.
171         *
172         * @param sCaption the caption of the new MenuSheet.
173         */
174        public MenuSheet(String sCaption) {
175            this(sCaption, null, '\0');
176        }
177    
178        /**
179         * Adds a MenuSheetObject to the end of this MenuSheet.
180         *
181         * <p>Should the MenuSheet currently be displayed, the new item will be displayed as
182         * well.</p>
183         *
184         * @override Never
185         *
186         * @param mso the new MenuSheetObject.
187         */
188        public synchronized void add(MenuSheetObject mso) {
189            if (m_msMergeParent == null) {
190                // we are not merged into some other MenuSheet, so we posess the peer.
191                synchronized (getPeerLock()) {
192                    // update peer
193    
194                    if (mso.isSeparator()) {
195                        if (m_jmPeer != null) {
196                            m_jmPeer.addSeparator();
197                            m_jmPeer.validate();
198                        }
199                    } else {
200                        if (m_jmPeer != null) {
201                            m_jmPeer.add(mso.getPeer());
202                            m_jmPeer.validate();
203                        }
204    
205                        if (m_jmbBarPeer != null) {
206                            JMenu jm = mso.getMenuPeer();
207                            m_jmbBarPeer.add(jm);
208                            if (HELP_MENU_TAG.equals(mso.getTag())) {
209                                m_jmbBarPeer.setHelpMenu(jm);
210                            }
211                            m_jmbBarPeer.validate();
212                        }
213                    }
214                }
215    
216                // insert MenuSheetObject
217                m_lmsoItems.addLast(mso); // Attention: Must be after peer update to make sure,
218                // we don't change the list while trying to create the
219                // peer.
220            } else {
221                // We are merged into another MenuSheet, so we don't manage the peer.
222    
223                m_lmsoItems.addLast(mso);
224    
225                // Tell merge parent to update peer.
226                if (!mso.isSeparator()) {
227                    int nIndex = m_lmsoItems.size() - 1; // nIndex == m_lmsoItems.indexOf (mso)
228    
229                    // index needs to be in peer "coordinates"
230                    for (Iterator i = m_lmsoItems.iterator(); i.hasNext(); ) {
231                        if (((MenuSheetObject)i.next()).isSeparator()) {
232                            nIndex--;
233                        }
234                    }
235    
236                    m_msMergeParent.mergedAdd(mso, nIndex);
237                }
238            }
239    
240            // Tell new item about its new environment
241            mso.setParent(this);
242            mso.setVisible(isVisible());
243            mso.attach(m_spAttached);
244            mso.attach(m_pAttached);
245        }
246    
247        /**
248         * Internal method used for updating merged peers correctly.
249         *
250         * @override Never
251         *
252         * @param mso the MenuSheet that was added in the merged MenuSheet.
253         * @param nIndex the peer index at which the element was added into the merged MenuSheet.
254         */
255        synchronized void mergedAdd(MenuSheetObject mso, int nIndex) {
256            if (m_msMergeParent == null) {
257                synchronized (getPeerLock()) {
258                    if (m_jmbBarPeer != null) {
259                        m_jmbBarPeer.add(mso.getMenuPeer(), nIndex + m_nMergedAt);
260                        m_jmbBarPeer.validate();
261                    }
262                }
263            } else {
264                m_msMergeParent.mergedAdd(mso, nIndex + m_nMergedAt);
265            }
266        }
267    
268        /**
269         * Remove a tagged top level item from the MenuSheet.
270         *
271         * <p>If an item with the given tag is found among the top level items of this
272         * MenuSheet, it is removed and the removed item is returned. Otherwise, the call is
273         * ignored.</p>
274         *
275         * <p>If the MenuSheet is currently on display, the peer will reflect the changes.</p>
276         *
277         * @override Never
278         *
279         * @param sTag the tag of the item to be removed.
280         *
281         * @return the removed item
282         */
283        public MenuSheetObject remove(String sTag) {
284            MenuSheetObject msoRemove = getTaggedItem(sTag, true);
285    
286            return ((msoRemove != null) ? (remove(msoRemove)) : (null));
287        }
288    
289        /**
290         * Remove a MenuSheetObject from the MenuSheet.
291         *
292         * <p>If the MenuSheet is currently on display, the peer will reflect the changes.</p>
293         *
294         * @override Never
295         *
296         * @param mso the MenuSheetObject to be removed.
297         *
298         * @return the removed MenuSheetObject.
299         */
300        public synchronized MenuSheetObject remove(MenuSheetObject msoRemove) {
301            // find the index of the item
302            int nIndex = m_lmsoItems.indexOf(msoRemove);
303            if (nIndex == -1) {
304                // item not found
305                return null;
306            }
307    
308            if (m_msMergeParent == null) {
309                // We have the peer, so we update it.
310                synchronized (getPeerLock()) {
311                    if (m_jmPeer != null) {
312                        m_jmPeer.remove(nIndex); // Separators can only be removed via index
313                        m_jmPeer.validate();
314                    }
315    
316                    if (!msoRemove.isSeparator()) {
317                        if (m_jmbBarPeer != null) {
318                            m_jmbBarPeer.remove(msoRemove.getMenuPeer());
319                            m_jmbBarPeer.validate();
320                        }
321                    }
322                }
323            } else {
324                // inform MenuSheet into which we are merged
325                m_msMergeParent.mergedRemove(msoRemove);
326            }
327    
328            // remove item
329            m_lmsoItems.remove(msoRemove);
330    
331            // set item's environment.
332            msoRemove.attach((SalesPoint)null);
333            msoRemove.attach((SaleProcess)null);
334            msoRemove.setVisible(false);
335            msoRemove.setParent(null);
336    
337            return msoRemove;
338        }
339    
340        /**
341         * Internal method used to properly update merged peers.
342         *
343         * @override Never
344         *
345         * @param mso the MenuSheetObject that was removed from the merged MenuSheet.
346         */
347        synchronized void mergedRemove(MenuSheetObject mso) {
348            if (m_msMergeParent == null) {
349                synchronized (getPeerLock()) {
350                    if ((m_jmbBarPeer != null) && (!mso.isSeparator())) {
351                        m_jmbBarPeer.remove(mso.getMenuPeer());
352                        m_jmbBarPeer.validate();
353                    }
354                }
355            } else {
356                m_msMergeParent.mergedRemove(mso);
357            }
358        }
359    
360        /**
361         * Return a <i>fail-fast</i>, readonly iterator of the items in this MenuSheet.
362         *
363         * <p>Fail-fast means, that this iterator will throw a <code>ConcurrentModificationException</code> when a
364         * structural change occured to the underlying MenuSheet.</p>
365         *
366         * <p>Also, the <code>remove()</code> method will throw an <code>UnsupportedOperationException</code>, as
367         * this is a readonly iterator.</p>
368         *
369         * @override Never
370         *
371         * @see ConcurrentModificationException
372         */
373        public Iterator iterator() {
374            class I implements Iterator {
375                private Iterator m_i;
376    
377                public I(Iterator i) {
378                    m_i = i;
379                }
380    
381                public boolean hasNext() {
382                    return m_i.hasNext();
383                }
384    
385                public Object next() {
386                    return m_i.next();
387                }
388    
389                public void remove() {
390                    throw new UnsupportedOperationException(
391                            "Please use the MenuSheet's remove() methods, not the iterator's.");
392                }
393            }
394    
395            return new I(m_lmsoItems.iterator());
396        }
397    
398        /**
399         * Internal method used when merging peers.
400         *
401         * @override Never
402         */
403        synchronized void setMergeParent(MenuSheet msMergeParent) {
404            m_msMergeParent = msMergeParent;
405        }
406    
407        /**
408         * Merges the peers of two MenuSheets. If a MenuSheet is already merged into this one,
409         * it will be removed and marked invisible.
410         *
411         * <p>The peers of the top level MenuSheetObjects of the given MenuSheet are merged
412         * into the JMenuBar peer of this MenuSheet. They will be inserted into the JMenuBar
413         * peer before the MenuSheetpObject with the given tag. If no such MenuSheetObject can
414         * be found in the MenuSheet they are appended to the end of the peer.</p>
415         *
416         * <p>Merging can always only result in a JMenuBar peer. A JMenu peer cannot be merged.
417         * However, merging can be nested. I.e. it is legal, to merge a MenuSheet, into whose
418         * peer another MenuSheet's peer has been merged, into a third MenuSheet.</p>
419         *
420         * <p>Although the peers of the two MenuSheets are merged, they stay independent with
421         * respect to anything else. The MenuSheetObjects of the merged MenuSheet can still
422         * only be accessed through that MenuSheet and vice-vera. Also, the attached SalesPoint
423         * and SaleProcess stay independent.</p>
424         *
425         * <p>For merging to function correctly, you must set the created JMenuBar in your
426         * JFrame. Something like this will do the trick:</p>
427         * <pre>
428         *   setJMenuBar (ms.mergePeers (msToMerge, "MERGE_BEFORE_THIS"));
429         * </pre>
430         *
431         * <p>This method is usually not called directly.</p>
432         *
433         * @param msToMerge the MenuSheet to be merged into this one.
434         * @param sBeforeTag before which tag to merge in the MenuSheet.
435         *
436         * @override Never
437         */
438        public final JMenuBar mergePeers(MenuSheet msToMerge, String sBeforeTag) {
439            synchronized (getPeerLock()) {
440                boolean fVisible = isVisible();
441    
442                if (fVisible) {
443                    setVisible(false);
444                }
445    
446                if (m_msMerged != null) {
447                    m_msMerged.setMergeParent(null);
448                }
449    
450                m_msMerged = msToMerge;
451                m_sMergedBefore = sBeforeTag;
452                m_nMergedAt = -1;
453    
454                if (m_msMerged != null) {
455                    m_msMerged.setMergeParent(this);
456                }
457    
458                if (fVisible) {
459                    setVisible(true);
460                }
461                if (m_msMergeParent != null) {
462                    return m_msMergeParent.remergePeers();
463                } else {
464                    return getMenuBar();
465                }
466            }
467        }
468    
469        /**
470         * Internal method used for proper merging of peers.
471         *
472         * @override Never
473         */
474        JMenuBar remergePeers() {
475            return mergePeers(m_msMerged, m_sMergedBefore);
476        }
477    
478        /**
479         * Get a MenuSheetObject by its tag.
480         *
481         * <p>This will iterate over all MenuSheetObjects in this MenuSheet and return the
482         * first one, that has the given tag.</p>
483         *
484         * @override Never
485         *
486         * @param sTag the tag to search for.
487         * @param fTopLevelOnly if true, only the direct elements in this MenuSheet are searched.
488         *
489         * @exception ConcurrentModificationException if the structure of the MenuSheet changed
490         * during the search.
491         *
492         * @return the first MenuSheetObject that has the given tag, if any.
493         */
494        public MenuSheetObject getTaggedItem(String sTag, boolean fTopLevelOnly) {
495            MenuSheetObject msoReturn = super.getTaggedItem(sTag, fTopLevelOnly);
496            if (msoReturn != null) {
497                return msoReturn;
498            }
499    
500            for (Iterator i = iterator(); i.hasNext(); ) {
501                MenuSheetObject mso = (MenuSheetObject)i.next();
502    
503                if (fTopLevelOnly) {
504                    String sCurTag = mso.getTag();
505    
506                    if (sCurTag.equals(sTag)) {
507                        return mso;
508                    }
509                } else {
510                    msoReturn = mso.getTaggedItem(sTag, fTopLevelOnly);
511    
512                    if (msoReturn != null) {
513                        return msoReturn;
514                    }
515                }
516            }
517    
518            return null;
519        }
520    
521        /**
522         * Attach a SalesPoint to this MenuSheet.
523         *
524         * @override Never
525         */
526        public synchronized SalesPoint attach(SalesPoint sp) {
527            for (Iterator i = iterator(); i.hasNext(); ) {
528                ((MenuSheetObject)i.next()).attach(sp);
529            }
530    
531            return super.attach(sp);
532        }
533    
534        /**
535         * Attach a SaleProcess to this MenuSheet.
536         *
537         * @override Never
538         */
539        public synchronized SaleProcess attach(SaleProcess p) {
540            for (Iterator i = iterator(); i.hasNext(); ) {
541                ((MenuSheetObject)i.next()).attach(p);
542            }
543    
544            return super.attach(p);
545        }
546    
547        /**
548         * Mark this MenuSheet, all its descendants and merged peer MenuSheets visible or
549         * invisible.
550         *
551         * @override Never
552         */
553        public synchronized void setVisible(boolean fVisible) {
554            super.setVisible(fVisible);
555    
556            for (Iterator i = iterator(); i.hasNext(); ) {
557                ((MenuSheetObject)i.next()).setVisible(fVisible);
558            }
559    
560            if (m_msMerged != null) {
561                m_msMerged.setVisible(fVisible);
562            }
563    
564            if (!fVisible) {
565                synchronized (getPeerLock()) {
566                    if (m_jmbBarPeer != null) {
567                        m_jmbBarPeer.removeAll();
568                        m_jmbBarPeer = null;
569                    }
570    
571                    if (m_jmPeer != null) {
572                        m_jmPeer.removeAll();
573                        m_jmPeer = null;
574                    }
575                }
576            }
577        }
578    
579        /**
580         * Set the caption of this MenuSheet.
581         *
582         * <p>If there is a peer it will reflect the changes immediately.</p>
583         *
584         * @override Never
585         *
586         * @param sCaption the new caption.
587         */
588        public void setCaption(String sCaption) {
589            super.setCaption(sCaption);
590    
591            synchronized (getPeerLock()) {
592                if (m_jmPeer != null) {
593                    m_jmPeer.setText(sCaption);
594                    m_jmPeer.validate();
595                }
596            }
597        }
598    
599        /**
600         * Set the mnemonic of this MenuSheet.
601         *
602         * <p>If there is a peer it will reflect the changes immediately.</p>
603         *
604         * @override Never
605         *
606         * @param sMnemonic the new mnemonic.
607         */
608        public void setMnemonic(char cMnemonic) {
609            m_cMnemonic = cMnemonic;
610    
611            synchronized (getPeerLock()) {
612                if (m_jmPeer != null) {
613                    m_jmPeer.setMnemonic(cMnemonic);
614                    m_jmPeer.validate();
615                }
616            }
617        }
618    
619        /**
620         * Set the ToolTip of this MenuSheet.
621         *
622         * <p>If there is a peer it will reflect the changes immediately.</p>
623         *
624         * @override Never
625         *
626         * @param s the new ToolTip-Text.
627         */
628        public void setToolTipText(String s) {
629            m_sToolTip = s;
630    
631            synchronized (getPeerLock()) {
632                if (m_jmPeer != null) {
633                    m_jmPeer.setToolTipText(s);
634                    m_jmPeer.validate();
635                }
636            }
637        }
638    
639        /**
640         * Set the default icon of this MenuSheet.
641         *
642         * <p>If there is a peer it will reflect the changes immediately.</p>
643         *
644         * @override Never
645         *
646         * @param iiImageIcon the new icon.
647         */
648        public void setDefaultIcon(ImageIcon iiImageIcon) {
649            setIcon(iiImageIcon, DEFAULT_IMAGE);
650        }
651    
652        /**
653         * Set the selected icon of this MenuSheet.
654         *
655         * <p>If there is a peer it will reflect the changes immediately.</p>
656         *
657         * @override Never
658         *
659         * @param iiImageIcon the new icon.
660         */
661        public void setSelectedIcon(ImageIcon iiImageIcon) {
662            setIcon(iiImageIcon, SELECTED_IMAGE);
663        }
664    
665        /**
666         * Set the disabled icon of this MenuSheet.
667         *
668         * <p>If there is a peer it will reflect the changes immediately.</p>
669         *
670         * @override Never
671         *
672         * @param iiImageIcon the new icon.
673         */
674        public void setDisabledIcon(ImageIcon iiImageIcon) {
675            setIcon(iiImageIcon, DISABLED_IMAGE);
676        }
677    
678        /**
679         * Set the disabled selected icon of this MenuSheet.
680         *
681         * <p>If there is a peer it will reflect the changes immediately.</p>
682         *
683         * @override Never
684         *
685         * @param iiImageIcon the new icon.
686         */
687        public void setDisabledSelectedIcon(ImageIcon iiImageIcon) {
688            setIcon(iiImageIcon, DISABLED_SELECTED_IMAGE);
689        }
690    
691        /**
692         * The JMenuItem peer of a MenuSheet is, of course, a JMenu.
693         *
694         * @override Never
695         */
696        public JMenuItem getPeer() {
697            synchronized (getPeerLock()) {
698                if (m_jmPeer == null) {
699                    m_jmPeer = new JMenu(getCaption());
700    
701                    // add Mnemonic to JMenu if exists
702                    if (m_cMnemonic != '\0') {
703                        m_jmPeer.setMnemonic(m_cMnemonic);
704    
705                    }
706                    if (m_sToolTip.compareTo("") != 0) {
707                        m_jmPeer.setToolTipText(m_sToolTip);
708                    }
709    
710                    if (m_aiImages != null) {
711                        // add DefaultIcon, if any
712                        if (m_aiImages[DEFAULT_IMAGE] != null) {
713                            m_jmPeer.setIcon(m_aiImages[DEFAULT_IMAGE]);
714                            // add PressedIcon, if any
715                        }
716                        if (m_aiImages[SELECTED_IMAGE] != null) {
717                            m_jmPeer.setSelectedIcon(m_aiImages[SELECTED_IMAGE]);
718                            // add DisabledIcon, if any
719                        }
720                        if (m_aiImages[DISABLED_IMAGE] != null) {
721                            m_jmPeer.setDisabledIcon(m_aiImages[DISABLED_IMAGE]);
722                            // add DisabledSelectedIcon, if any
723                        }
724                        if (m_aiImages[DISABLED_SELECTED_IMAGE] != null) {
725                            m_jmPeer.setDisabledSelectedIcon(m_aiImages[DISABLED_SELECTED_IMAGE]);
726                        }
727                    }
728    
729                    for (Iterator i = iterator(); i.hasNext(); ) {
730                        MenuSheetObject mso = (MenuSheetObject)i.next();
731    
732                        if (mso.isSeparator()) {
733                            m_jmPeer.addSeparator();
734                        } else {
735                            m_jmPeer.add(mso.getPeer());
736                        }
737                    }
738                }
739            }
740    
741            return m_jmPeer;
742        }
743    
744        /**
745         * For MenuSheets there is no difference between JMenuItem and JMenu peer, they are
746         * both JMenus.
747         *
748         * @override Never
749         */
750        public JMenu getMenuPeer() {
751            return (JMenu)getPeer();
752        }
753    
754        /**
755         * Return the JMenuBar peer.
756         *
757         * <p>For a MenuSheet there is a special peer: the JMenuBar peer. All items of this
758         * MenuSheet will present their JMenu peer in the JMenuBar. Only MenuSheetSeparators
759         * are not displayed in a JMenuBar representation. Merged peers are only displayed in
760         * the JMenuBar representation.</p>
761         *
762         * @override Never
763         */
764        public JMenuBar getMenuBar() {
765            synchronized (getPeerLock()) {
766                if (m_jmbBarPeer == null) {
767                    boolean fResolvedMerge = false;
768    
769                    m_jmbBarPeer = new JMenuBar();
770    
771                    for (Iterator i = iterator(); i.hasNext(); ) {
772                        MenuSheetObject mso = (MenuSheetObject)i.next();
773    
774                        if ((!fResolvedMerge) && (m_msMerged != null)) {
775                            if (mso.getTag().equals(m_sMergedBefore)) {
776    
777                                m_nMergedAt = m_jmbBarPeer.getMenuCount();
778                                synchronized (m_msMerged) {
779                                    MenuElement[] ajmMerged = m_msMerged.getMenuBar().getSubElements();
780                                    m_msMerged.getMenuBar().removeAll();
781    
782                                    for (int n = 0; n < ajmMerged.length; n++) {
783                                        m_jmbBarPeer.add((JMenu)ajmMerged[n]);
784                                    }
785                                }
786    
787                                fResolvedMerge = true;
788                            }
789                        }
790    
791                        if (!mso.isSeparator()) {
792                            m_jmbBarPeer.add(mso.getMenuPeer());
793                            if (HELP_MENU_TAG.equals(mso.getTag())) {
794                                m_jmbBarPeer.setHelpMenu(mso.getMenuPeer());
795                            }
796                        }
797                    }
798    
799                    if ((!fResolvedMerge) && (m_msMerged != null)) {
800                        // mark merge at end !
801                        m_sMergedBefore = null;
802                        m_nMergedAt = m_jmbBarPeer.getMenuCount();
803    
804                        synchronized (m_msMerged) {
805                            MenuElement[] ajmMerged = m_msMerged.getMenuBar().getSubElements();
806                            m_msMerged.getMenuBar().removeAll();
807    
808                            for (int n = 0; n < ajmMerged.length; n++) {
809                                m_jmbBarPeer.add((JMenu)ajmMerged[n]);
810                            }
811                        }
812                    }
813                }
814            }
815    
816            return m_jmbBarPeer;
817        }
818    
819        /**
820         * Get the Mnemonic of this MenuSheet.
821         *
822         * @override Never
823         *
824         * @return the mnemonic of this MenuSheet.
825         */
826        public char getMnemonic() {
827            return m_cMnemonic;
828        }
829    
830        /**
831         * Get the ToolTip of this MenuSheet.
832         *
833         * @override Never
834         *
835         * @return the ToolTip-String of this MenuSheet.
836         */
837        public String getToolTipText() {
838            return m_sToolTip;
839        }
840    
841        /**
842         * Get the default icon of this MenuSheet.
843         *
844         * @override Never
845         *
846         * @return the default icon of this MenuSheet.
847         */
848        public ImageIcon getDefaultIcon() {
849            return (m_aiImages != null) ? (m_aiImages[DEFAULT_IMAGE]) : (null);
850        }
851    
852        /**
853         * Get the selected icon of this MenuSheet.
854         *
855         * @override Never
856         *
857         * @return the pressed icon of this MenuSheet.
858         */
859        public ImageIcon getSelectedIcon() {
860            return (m_aiImages != null) ? (m_aiImages[SELECTED_IMAGE]) : (null);
861        }
862    
863        /**
864         * Get the disabled item of this MenuSheet.
865         *
866         * @override Never
867         *
868         * @return the disabled icon of this MenuSheet.
869         */
870        public ImageIcon getDisabledIcon() {
871            return (m_aiImages != null) ? (m_aiImages[DISABLED_IMAGE]) : (null);
872        }
873    
874        /**
875         * Get the disabled selected item of this MenuSheet.
876         *
877         * @override Never
878         *
879         * @return the disabled selected icon of this MenuSheet.
880         */
881        public ImageIcon getDisabledSelectedIcon() {
882            return (m_aiImages != null) ? (m_aiImages[DISABLED_SELECTED_IMAGE]) : (null);
883        }
884    
885        /**
886         * A tag that will identify the help menu, should this MenuSheet be displayed as a
887         * JMenuBar.
888         */
889        public final static String HELP_MENU_TAG = "__TAG:_HELP_MENU";
890        // A Tag that will identify the Image for the DefaultIcon
891        private final static int DEFAULT_IMAGE = 0;
892        // A Tag that will identify the Image for the SelectedIcon
893        private final static int SELECTED_IMAGE = 1;
894        // A Tag that will identify the Image for the DisabledIcon
895        private final static int DISABLED_IMAGE = 2;
896        // A Tag that will identify the Image for the DisabledSelectedIcon
897        private final static int DISABLED_SELECTED_IMAGE = 3;
898    }