? ant/external/ant-api-1.6.3.zip ? ant/external/ant-docs-1.6.3.zip ? ant/external/ant-libs-1.6.3.zip ? ant/external/ant-misc-1.6.3.zip ? cpplite/.DS_Store ? installer/.DS_Store ? installer/mac/.DS_Store ? nbbuild/netbeans.zip ? nbbuild/testuserdir2 ? openide/awt/test/lib ? openide/awt/test/results ? openide/awt/test/work ? xtest/external/ant-1.4.1.jar Index: core/ui/src/org/netbeans/core/ui/warmup/ContextMenuWarmUpTask.java =================================================================== RCS file: /cvs/core/ui/src/org/netbeans/core/ui/warmup/ContextMenuWarmUpTask.java,v retrieving revision 1.2 diff -u -r1.2 ContextMenuWarmUpTask.java --- core/ui/src/org/netbeans/core/ui/warmup/ContextMenuWarmUpTask.java 4 Jun 2005 05:16:00 -0000 1.2 +++ core/ui/src/org/netbeans/core/ui/warmup/ContextMenuWarmUpTask.java 13 Jul 2005 12:53:21 -0000 @@ -38,8 +38,8 @@ public void run() { // For first context menu. org.openide.actions.ActionManager.getDefault().getContextActions(); - new org.openide.awt.JPopupMenuPlus(); - new org.openide.awt.JInlineMenu(); +// new org.openide.awt.JPopupMenuPlus(); +// new org.openide.awt.JInlineMenu(); new javax.swing.JMenuItem(); // #30676 ToolsAction popup warm up. Index: editor/nbproject/project.properties =================================================================== RCS file: /cvs/editor/nbproject/project.properties,v retrieving revision 1.14 diff -u -r1.14 project.properties --- editor/nbproject/project.properties 17 Jun 2005 09:20:51 -0000 1.14 +++ editor/nbproject/project.properties 13 Jul 2005 12:53:29 -0000 @@ -9,7 +9,7 @@ # Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun # Microsystems, Inc. All Rights Reserved. -spec.version.base=1.22.0 +spec.version.base=1.22.1 is.autoload=true javadoc.arch=${basedir}/arch/arch-editor.xml Index: editor/nbproject/project.xml =================================================================== RCS file: /cvs/editor/nbproject/project.xml,v retrieving revision 1.18 diff -u -r1.18 project.xml --- editor/nbproject/project.xml 4 Jun 2005 05:16:08 -0000 1.18 +++ editor/nbproject/project.xml 13 Jul 2005 12:53:29 -0000 @@ -39,7 +39,7 @@ - 6.2 + 6.4 @@ -71,7 +71,7 @@ - 6.2 + 6.5 Index: editor/src/org/netbeans/modules/editor/NbCodeFoldingAction.java =================================================================== RCS file: /cvs/editor/src/org/netbeans/modules/editor/NbCodeFoldingAction.java,v retrieving revision 1.11 diff -u -r1.11 NbCodeFoldingAction.java --- editor/src/org/netbeans/modules/editor/NbCodeFoldingAction.java 5 Apr 2005 13:38:00 -0000 1.11 +++ editor/src/org/netbeans/modules/editor/NbCodeFoldingAction.java 13 Jul 2005 12:53:29 -0000 @@ -18,6 +18,7 @@ import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.ImageIcon; +import javax.swing.JComponent; import javax.swing.JEditorPane; import javax.swing.JMenu; import javax.swing.JMenuItem; @@ -34,6 +35,7 @@ import org.openide.loaders.DataObject; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; +import org.openide.awt.DynamicMenuContent; import org.openide.util.actions.Presenter; import org.openide.util.actions.SystemAction; @@ -102,7 +104,7 @@ } - public class CodeFoldsMenu extends JMenu{ + public class CodeFoldsMenu extends JMenu implements DynamicMenuContent { public CodeFoldsMenu(){ super(); } @@ -113,6 +115,15 @@ //setIcon(new ImageIcon(org.openide.util.Utilities.loadImage("org/netbeans/modules/editor/resources/empty.gif"))); //NOI18N //#40585 fix end org.openide.awt.Mnemonics.setLocalizedText(this, s); + } + + public JComponent[] getMenuPresenters() { + return new JComponent[] { this }; + } + + public JComponent[] synchMenuPresenters(JComponent[] items) { + getPopupMenu(); + return items; } public JPopupMenu getPopupMenu(){ Index: editor/src/org/netbeans/modules/editor/NbEditorKit.java =================================================================== RCS file: /cvs/editor/src/org/netbeans/modules/editor/NbEditorKit.java,v retrieving revision 1.84 diff -u -r1.84 NbEditorKit.java --- editor/src/org/netbeans/modules/editor/NbEditorKit.java 24 May 2005 12:46:51 -0000 1.84 +++ editor/src/org/netbeans/modules/editor/NbEditorKit.java 13 Jul 2005 12:53:29 -0000 @@ -13,6 +13,7 @@ package org.netbeans.modules.editor; +import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; @@ -21,6 +22,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import javax.swing.JComponent; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; @@ -34,6 +36,7 @@ import org.netbeans.editor.ActionFactory; import org.netbeans.editor.EditorUI; import org.netbeans.editor.ext.ExtKit; +import org.openide.awt.DynamicMenuContent; import org.openide.util.actions.SystemAction; import org.openide.util.actions.Presenter; import org.openide.actions.UndoAction; @@ -308,14 +311,21 @@ if (action != null) { JMenuItem item = createLocalizedMenuItem(action); - item.setEnabled(action.isEnabled()); - Object helpID = action.getValue ("helpID"); // NOI18N - if (helpID != null && (helpID instanceof String)) { - item.putClientProperty ("HelpID", helpID); // NOI18N + if (item instanceof DynamicMenuContent) { + Component[] cmps = ((DynamicMenuContent)item).getMenuPresenters(); + for (int i = 0; i < cmps.length; i++) { + popupMenu.add(cmps[i]); + } + } else { + item.setEnabled(action.isEnabled()); + Object helpID = action.getValue ("helpID"); // NOI18N + if (helpID != null && (helpID instanceof String)) { + item.putClientProperty ("HelpID", helpID); // NOI18N + } + assignAccelerator(component.getKeymap(), action, item); + debugPopupMenuItem(item, action); + popupMenu.add(item); } - assignAccelerator(component.getKeymap(), action, item); - debugPopupMenuItem(item, action); - popupMenu.add(item); } } @@ -326,21 +336,9 @@ if (tc != null) { // Add all the actions Action[] actions = tc.getActions(); - for (int i = 0; i < actions.length; i++) { - Action action = actions[i]; - action = translateContextLookupAction(contextLookup, action); - - if (action != null){ - JMenuItem item = createLocalizedMenuItem(action); - assignAccelerator( - (Keymap)Lookup.getDefault().lookup(Keymap.class), - action, - item - ); - - debugPopupMenuItem(item, action); - popupMenu.add(item); - } + Component[] comps = org.openide.util.Utilities.actionsToPopup(actions, contextLookup).getComponents(); + for (int i = 0; i < comps.length; i++) { + popupMenu.add(comps[i]); } } } @@ -369,14 +367,23 @@ action = translateContextLookupAction(contextLookup, action); JMenuItem item = createLocalizedMenuItem(action); - if (item != null) { // && !(item instanceof JMenu)) - assignAccelerator( - (Keymap)Lookup.getDefault().lookup(Keymap.class), - action, - item - ); - debugPopupMenuItem(item, action); - popupMenu.add(item); + if (item != null) { + if (item instanceof DynamicMenuContent) { + Component[] cmps = ((DynamicMenuContent)item).getMenuPresenters(); + for (int i = 0; i < cmps.length; i++) { + popupMenu.add(cmps[i]); + } + } else { + if (!(item instanceof JMenu)) { + assignAccelerator( + (Keymap)Lookup.getDefault().lookup(Keymap.class), + action, + item + ); + } + debugPopupMenuItem(item, action); + popupMenu.add(item); + } } return; Index: i18n/src/org/netbeans/modules/i18n/I18nGroupAction.java =================================================================== RCS file: /cvs/i18n/src/org/netbeans/modules/i18n/I18nGroupAction.java,v retrieving revision 1.13 diff -u -r1.13 I18nGroupAction.java --- i18n/src/org/netbeans/modules/i18n/I18nGroupAction.java 5 Apr 2005 13:37:57 -0000 1.13 +++ i18n/src/org/netbeans/modules/i18n/I18nGroupAction.java 13 Jul 2005 12:53:37 -0000 @@ -152,6 +152,10 @@ Actions.setMenuText(this, action.getName(), isMenu); this.isMenu = isMenu; + if (isMenu) { + // mkleint doens't seem to be dynamic at all, just set it for main menu.. + createMenuItems(); + } } /** Creates LazyPopup menu item. */ Index: ide/applemenu/src/org/netbeans/modules/applemenu/layer.xml =================================================================== RCS file: /cvs/ide/applemenu/src/org/netbeans/modules/applemenu/layer.xml,v retrieving revision 1.7 diff -u -r1.7 layer.xml --- ide/applemenu/src/org/netbeans/modules/applemenu/layer.xml 21 Jun 2005 09:20:21 -0000 1.7 +++ ide/applemenu/src/org/netbeans/modules/applemenu/layer.xml 13 Jul 2005 12:53:37 -0000 @@ -15,7 +15,7 @@ - Index: ide/launcher/unix/netbeans =================================================================== RCS file: /cvs/ide/launcher/unix/netbeans,v retrieving revision 1.18 diff -u -r1.18 netbeans --- ide/launcher/unix/netbeans 14 Jun 2005 15:43:06 -0000 1.18 +++ ide/launcher/unix/netbeans 13 Jul 2005 12:53:37 -0000 @@ -65,11 +65,14 @@ nbexec="$progdir"/../platform5/lib/nbexec +# in case of macosx, the apple.laf.useScreenMenuBar property should be ideally in the Info.plist file +# but it doesn't get propagated into the executed java VM. case "`uname`" in Darwin*) "$nbexec" \ --jdkhome "$netbeans_jdkhome" \ -J-Dcom.apple.mrj.application.apple.menu.about.name=NetBeans \ + -J-Dapple.laf.useScreenMenuBar=true \ -J-Xdock:name=NetBeans \ "-J-Xdock:icon=$progdir/../nb4.1/netbeans.icns" \ --branding nb \ Index: installer/mac/Info.plist =================================================================== RCS file: /cvs/installer/mac/Info.plist,v retrieving revision 1.1 diff -u -r1.1 Info.plist --- installer/mac/Info.plist 18 Aug 2004 08:16:40 -0000 1.1 +++ installer/mac/Info.plist 13 Jul 2005 12:53:39 -0000 @@ -1,6 +1,7 @@ - - + + CFBundleName @@ -26,5 +27,14 @@ CFBundleIconFile @ICONFILENAME@ + + Java + + Properties + + apple.laf.useScreenMenuBar + true + + Index: javadoc/manifest.mf =================================================================== RCS file: /cvs/javadoc/manifest.mf,v retrieving revision 1.68 diff -u -r1.68 manifest.mf --- javadoc/manifest.mf 6 Apr 2005 00:06:48 -0000 1.68 +++ javadoc/manifest.mf 13 Jul 2005 12:53:55 -0000 @@ -4,7 +4,7 @@ OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/javadoc/Bundle.properties OpenIDE-Module-Layer: org/netbeans/modules/javadoc/resources/mf-layer.xml OpenIDE-Module-Requires: org.openide.modules.InstalledFileLocator -OpenIDE-Module-Specification-Version: 1.15 +OpenIDE-Module-Specification-Version: 1.16 Name: org/netbeans/modules/javadoc/comments/AutoCommentAction.class OpenIDE-Module-Class: Action Index: javadoc/nbproject/project.xml =================================================================== RCS file: /cvs/javadoc/nbproject/project.xml,v retrieving revision 1.8 diff -u -r1.8 project.xml --- javadoc/nbproject/project.xml 4 Jun 2005 05:16:33 -0000 1.8 +++ javadoc/nbproject/project.xml 13 Jul 2005 12:53:55 -0000 @@ -56,7 +56,7 @@ - 6.2 + 6.4 @@ -88,7 +88,7 @@ - 6.2 + 6.5 Index: javadoc/src/org/netbeans/modules/javadoc/search/IndexOverviewAction.java =================================================================== RCS file: /cvs/javadoc/src/org/netbeans/modules/javadoc/search/IndexOverviewAction.java,v retrieving revision 1.14 diff -u -r1.14 IndexOverviewAction.java --- javadoc/src/org/netbeans/modules/javadoc/search/IndexOverviewAction.java 5 Apr 2005 13:37:58 -0000 1.14 +++ javadoc/src/org/netbeans/modules/javadoc/search/IndexOverviewAction.java 13 Jul 2005 12:53:55 -0000 @@ -21,6 +21,7 @@ import java.util.*; import java.lang.ref.Reference; import java.lang.ref.WeakReference; +import javax.swing.JComponent; import javax.swing.JMenu; import javax.swing.JMenuItem; import org.openide.ErrorManager; @@ -31,6 +32,7 @@ import org.openide.filesystems.FileSystem; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; +import org.openide.awt.DynamicMenuContent; import org.openide.util.actions.SystemAction; import org.openide.util.actions.Presenter; @@ -73,7 +75,7 @@ * list of filesystems and finding their titles. When the popup for it * is created, it will create submenuitems for each available index. */ - private final class IndexMenu extends JMenu implements HelpCtx.Provider { + private final class IndexMenu extends JMenu implements HelpCtx.Provider, DynamicMenuContent { private int itemHash = 0; @@ -86,15 +88,26 @@ return IndexOverviewAction.this.getHelpCtx(); } - public void addNotify() { - if (err.isLoggable(ErrorManager.INFORMATIONAL)) { - err.log("addNotify"); - } - super.addNotify(); - IndexBuilder.getDefault(); + public JComponent[] getMenuPresenters() { + getPopupMenu2(); + return new JComponent[] {this}; + } + + public JComponent[] synchMenuPresenters(JComponent[] items) { + System.out.println("synchronizing doc root."); + getPopupMenu2(); + return items; } - public JPopupMenu getPopupMenu() { +// public void addNotify() { +// if (err.isLoggable(ErrorManager.INFORMATIONAL)) { +// err.log("addNotify"); +// } +// super.addNotify(); +// IndexBuilder.getDefault(); +// } + + public void getPopupMenu2() { List[] data = IndexBuilder.getDefault().getIndices(); int newHash = computeDataHash(data); if (newHash != itemHash) { @@ -122,7 +135,6 @@ add(dummy); } } - return super.getPopupMenu(); } private int computeDataHash(List[] data) { Index: junit/manifest.mf =================================================================== RCS file: /cvs/junit/manifest.mf,v retrieving revision 1.38 diff -u -r1.38 manifest.mf --- junit/manifest.mf 6 Apr 2005 00:06:48 -0000 1.38 +++ junit/manifest.mf 13 Jul 2005 12:54:01 -0000 @@ -1,7 +1,7 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.junit/2 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/junit/Bundle.properties -OpenIDE-Module-Specification-Version: 2.15 +OpenIDE-Module-Specification-Version: 2.16 OpenIDE-Module-Layer: org/netbeans/modules/junit/resources/layer.xml OpenIDE-Module-Java-Dependencies: Java > 1.4 Index: junit/nbproject/project.xml =================================================================== RCS file: /cvs/junit/nbproject/project.xml,v retrieving revision 1.6 diff -u -r1.6 project.xml --- junit/nbproject/project.xml 4 Jun 2005 05:16:36 -0000 1.6 +++ junit/nbproject/project.xml 13 Jul 2005 12:54:01 -0000 @@ -112,7 +112,7 @@ - 6.2 + 6.4 @@ -144,7 +144,7 @@ - 6.2 + 6.5 Index: junit/src/org/netbeans/modules/junit/TestsAction.java =================================================================== RCS file: /cvs/junit/src/org/netbeans/modules/junit/TestsAction.java,v retrieving revision 1.10 diff -u -r1.10 TestsAction.java --- junit/src/org/netbeans/modules/junit/TestsAction.java 5 Apr 2005 13:38:02 -0000 1.10 +++ junit/src/org/netbeans/modules/junit/TestsAction.java 13 Jul 2005 12:54:01 -0000 @@ -86,9 +86,23 @@ SystemAction.get (OpenTestAction.class), }; + private JMenu menuitem; public JMenuItem getMenuPresenter () { - JMenu menu = new LazyMenu (getName ()); - return menu; + if (menuitem == null) { + // mkleint: just ignore theh lazy conructuction and do everything up front. + // simplifies code and works on macosx + menuitem = new JMenu (getName ()); + // Conventional not to set an icon here. + for (int i = 0; i < grouped.length; i++) { + SystemAction action = grouped[i]; + if (action == null) { + menuitem.addSeparator (); + } else if (action instanceof Presenter.Menu) { + menuitem.add (((Presenter.Menu) action).getMenuPresenter()); + } + } + } + return menuitem; } public JMenuItem getPopupPresenter () { @@ -116,32 +130,6 @@ } } return toolbar; - } - - /** - * Lazy menu which when added to its parent menu, will begin creating the - * list of submenu items and finding their presenters. - */ - private final class LazyMenu extends JMenu { - - public LazyMenu(String name) { - super(name); - } - - public JPopupMenu getPopupMenu() { - if (getItemCount() == 0) { - for (int i = 0; i < grouped.length; i++) { - SystemAction action = grouped[i]; - if (action == null) { - addSeparator (); - } else if (action instanceof Presenter.Menu) { - add (((Presenter.Menu) action).getMenuPresenter ()); - } - } - } - return super.getPopupMenu(); - } - } } Index: openide/actions/manifest.mf =================================================================== RCS file: /cvs/openide/actions/manifest.mf,v retrieving revision 1.3 diff -u -r1.3 manifest.mf --- openide/actions/manifest.mf 21 Apr 2005 20:12:12 -0000 1.3 +++ openide/actions/manifest.mf 13 Jul 2005 12:54:06 -0000 @@ -1,5 +1,5 @@ Manifest-Version: 1.0 OpenIDE-Module: org.openide.actions -OpenIDE-Module-Specification-Version: 6.2 +OpenIDE-Module-Specification-Version: 6.3 OpenIDE-Module-Localizing-Bundle: org/openide/actions/Bundle.properties Index: openide/actions/nbproject/project.xml =================================================================== RCS file: /cvs/openide/actions/nbproject/project.xml,v retrieving revision 1.4 diff -u -r1.4 project.xml --- openide/actions/nbproject/project.xml 25 May 2005 23:56:54 -0000 1.4 +++ openide/actions/nbproject/project.xml 13 Jul 2005 12:54:06 -0000 @@ -22,7 +22,7 @@ - 6.2 + 6.4 @@ -38,7 +38,7 @@ - 6.2 + 6.5 Index: openide/actions/src/org/openide/actions/NewAction.java =================================================================== RCS file: /cvs/openide/actions/src/org/openide/actions/NewAction.java,v retrieving revision 1.1 diff -u -r1.1 NewAction.java --- openide/actions/src/org/openide/actions/NewAction.java 21 Apr 2005 20:12:16 -0000 1.1 +++ openide/actions/src/org/openide/actions/NewAction.java 13 Jul 2005 12:54:06 -0000 @@ -128,7 +128,7 @@ public javax.swing.JMenuItem getMenuPresenter() { return new Actions.SubMenu(this, model, false); } - + public javax.swing.JMenuItem getPopupPresenter() { return new Actions.SubMenu(this, model, true); } Index: openide/actions/src/org/openide/actions/PasteAction.java =================================================================== RCS file: /cvs/openide/actions/src/org/openide/actions/PasteAction.java,v retrieving revision 1.1 diff -u -r1.1 PasteAction.java --- openide/actions/src/org/openide/actions/PasteAction.java 21 Apr 2005 20:12:17 -0000 1.1 +++ openide/actions/src/org/openide/actions/PasteAction.java 13 Jul 2005 12:54:08 -0000 @@ -61,7 +61,7 @@ * getValue ("delegates") than those actions are offered as * subelements by the paste action presenter. */ -public final class PasteAction extends CallbackSystemAction { +public final class PasteAction extends CallbackSystemAction { /** Imlementation of ActSubMenuInt */ private static ActSubMenuModel globalModel; @@ -98,11 +98,7 @@ public javax.swing.JMenuItem getMenuPresenter() { return new Actions.SubMenu(this, model(), false); } - - public javax.swing.JMenuItem getPopupPresenter() { - return new Actions.SubMenu(this, model(), true); - } - + public Action createContextAwareInstance(Lookup actionContext) { return new DelegateAction(this, actionContext); } Index: openide/actions/src/org/openide/actions/ToolsAction.java =================================================================== RCS file: /cvs/openide/actions/src/org/openide/actions/ToolsAction.java,v retrieving revision 1.1 diff -u -r1.1 ToolsAction.java --- openide/actions/src/org/openide/actions/ToolsAction.java 21 Apr 2005 20:12:19 -0000 1.1 +++ openide/actions/src/org/openide/actions/ToolsAction.java 13 Jul 2005 12:54:08 -0000 @@ -14,7 +14,6 @@ import org.openide.actions.ActionManager; import org.openide.awt.Actions; -import org.openide.awt.JInlineMenu; import org.openide.util.ContextAwareAction; import org.openide.util.HelpCtx; import org.openide.util.Lookup; @@ -27,6 +26,7 @@ import javax.swing.*; import javax.swing.event.*; +import org.openide.awt.DynamicMenuContent; /** A "meta-action" that displays (in a submenu) a list of enabled actions provided by modules. @@ -194,7 +194,7 @@ /** Inline menu that watches model changes only when really needed. */ - private static final class Inline extends JInlineMenu implements PropertyChangeListener, Runnable { + private static final class Inline extends JMenuItem implements DynamicMenuContent { static final long serialVersionUID = 2269006599727576059L; /** timestamp of the beginning of the last regeneration */ @@ -205,64 +205,66 @@ Inline(Action toolsAction) { this.toolsAction = toolsAction; - putClientProperty("hack.preShowUpdater", this); +// putClientProperty("hack.preShowUpdater", this); } - /** By calling this method, our parent notifies us we've to be keep - * updated, so we start listening on SystemAction changes, and - * schedule updating Runnable imediately. - */ - public void addNotify() { - // We were not notified by our parent, too bad - if (timestamp != gl().getTimestamp()) { - SwingUtilities.invokeLater(this); - } - - gl().addPropertyChangeListener(this); - super.addNotify(); - } - - /** By calling this method, our parent notifies us we don't have - * to be up-to-date more, so we switch to lazy mode and discard any - * pending updates. - */ - public void removeNotify() { - gl().removePropertyChangeListener(this); - super.removeNotify(); - } - - /** Change of model. - */ - public void propertyChange(PropertyChangeEvent ev) { - String prop = ev.getPropertyName(); - - if ((prop == null) || prop.equals(G.PROP_STATE)) { - SwingUtilities.invokeLater(this); - } - } - - /** Runs the update */ - public void run() { +// /** By calling this method, our parent notifies us we've to be keep +// * updated, so we start listening on SystemAction changes, and +// * schedule updating Runnable imediately. +// */ +// public void addNotify() { +//// // We were not notified by our parent, too bad +//// if (timestamp != gl().getTimestamp()) { +//// SwingUtilities.invokeLater(this); +//// } +//// +//// gl().addPropertyChangeListener(this); +// super.addNotify(); +// } +// +// /** By calling this method, our parent notifies us we don't have +// * to be up-to-date more, so we switch to lazy mode and discard any +// * pending updates. +// */ +// public void removeNotify() { +//// gl().removePropertyChangeListener(this); +// super.removeNotify(); +// } + +// /** Change of model. +// */ +// public void propertyChange(PropertyChangeEvent ev) { +// String prop = ev.getPropertyName(); +// +// if ((prop == null) || prop.equals(G.PROP_STATE)) { +// SwingUtilities.invokeLater(this); +// } +// } + + public JComponent[] synchMenuPresenters(JComponent[] items) { if (timestamp == gl().getTimestamp()) { - return; + return items; } - // generate directly list of menu items List l = generate(toolsAction, true); - setMenuItems((JMenuItem[]) l.toArray(new JMenuItem[l.size()])); timestamp = gl().getTimestamp(); + return (JMenuItem[]) l.toArray(new JMenuItem[l.size()]); } + + + public JComponent[] getMenuPresenters() { + return synchMenuPresenters(new JComponent[0]); + } } //-------------------------------------------------- /** Inline menu that is either empty or contains one submenu.*/ - private static final class Popup extends JInlineMenu implements Runnable { + private static final class Popup extends JMenuItem implements DynamicMenuContent { static final long serialVersionUID = 2269006599727576059L; /** sub menu */ private JMenu menu = new MyMenu(); - private boolean inited = false; /** Associated tools action. */ private Action toolsAction; @@ -272,27 +274,36 @@ this.toolsAction = toolsAction; HelpCtx.setHelpIDString(menu, ToolsAction.class.getName()); - // This can be probably swapped as the popup is short time entity and our hack - // will be called just once and very early after the constructor. - // run(); - putClientProperty("hack.preShowUpdater", this); - } - - public void addNotify() { - if (!inited) { // should not happen - SwingUtilities.invokeLater(this); // too late to do it here - } - - super.addNotify(); - } - - /** Runs the update */ - public void run() { - if (!inited) { - setMenuItems(gl().isPopupEnabled(toolsAction) ? new JMenuItem[] { menu } : new JMenuItem[0]); - inited = true; - } - } +// // This can be probably swapped as the popup is short time entity and our hack +// // will be called just once and very early after the constructor. +// // run(); +// putClientProperty("hack.preShowUpdater", this); + } + +// public void addNotify() { +// if (!inited) { // should not happen +// SwingUtilities.invokeLater(this); // too late to do it here +// } +// +// super.addNotify(); +// } + + public JComponent[] synchMenuPresenters(JComponent[] items) { + return gl().isPopupEnabled(toolsAction) ? new JMenuItem[] { menu } : new JMenuItem[0]; + } + + + public JComponent[] getMenuPresenters() { + return synchMenuPresenters(new JComponent[0]); + } + +// /** Runs the update */ +// public void run() { +// if (!inited) { +// setMenuItems(gl().isPopupEnabled(toolsAction) ? new JMenuItem[] { menu } : new JMenuItem[0]); +// inited = true; +// } +// } /** A special menu that will properly update its submenu before posting */ private class MyMenu extends org.openide.awt.JMenuPlus implements PopupMenuListener { Index: openide/awt/apichanges.xml =================================================================== RCS file: /cvs/openide/awt/apichanges.xml,v retrieving revision 1.5 diff -u -r1.5 apichanges.xml --- openide/awt/apichanges.xml 9 May 2005 07:20:34 -0000 1.5 +++ openide/awt/apichanges.xml 13 Jul 2005 12:54:08 -0000 @@ -17,6 +17,31 @@ AWT API + + + DynamicMenuContent interface added + + + + + + In order to support MacOSX top menus and to fix problems with deprecated JInlineMenu, this new + interface was added that allows to handle dynamic content in Presenter.Menu + and Presenter.Popup. + If the instance returned by Presenter.Menu/Popup is an instance of DynamicMenuContent, it's methods are + consulted when creating/updating the menu. + JInlineMenu rewritten to use this new approach in a backward compatible way, however changed during visibility of the menu are not supported. + JMenuPlus and JPopupMenuPlus are deprecated and behave exactly like their standard Swing counterparts. + Actions.Submenu and Actions.MenuItem now implement DynamicMenuContent interface. + + + + + + + + + Make IDE's status bar pluggable. @@ -48,7 +73,7 @@ - + HTML browser factory deprecated, use lookup instead @@ -61,7 +86,7 @@ - + Display names for toolbars @@ -85,7 +110,7 @@ - + Cleaned up accidentally public members of Toolbar Index: openide/awt/manifest.mf =================================================================== RCS file: /cvs/openide/awt/manifest.mf,v retrieving revision 1.5 diff -u -r1.5 manifest.mf --- openide/awt/manifest.mf 6 May 2005 08:09:46 -0000 1.5 +++ openide/awt/manifest.mf 13 Jul 2005 12:54:08 -0000 @@ -1,5 +1,5 @@ Manifest-Version: 1.0 OpenIDE-Module: org.openide.awt -OpenIDE-Module-Specification-Version: 6.4 +OpenIDE-Module-Specification-Version: 6.5 OpenIDE-Module-Localizing-Bundle: org/openide/awt/Bundle.properties Index: openide/awt/nbproject/project.properties =================================================================== RCS file: /cvs/openide/awt/nbproject/project.properties,v retrieving revision 1.3 diff -u -r1.3 project.properties --- openide/awt/nbproject/project.properties 25 Apr 2005 12:44:36 -0000 1.3 +++ openide/awt/nbproject/project.properties 13 Jul 2005 12:54:08 -0000 @@ -15,4 +15,5 @@ #javadoc.arch=${basedir}/../arch/arch-openide-awt.xml #javadoc.docfiles=${basedir}/api/doc #javadoc.apichanges=${basedir}/api/apichanges.xml +javadoc.apichanges=${basedir}/apichanges.xml Index: openide/awt/nbproject/project.xml =================================================================== RCS file: /cvs/openide/awt/nbproject/project.xml,v retrieving revision 1.4 diff -u -r1.4 project.xml --- openide/awt/nbproject/project.xml 25 May 2005 23:56:54 -0000 1.4 +++ openide/awt/nbproject/project.xml 13 Jul 2005 12:54:08 -0000 @@ -22,7 +22,7 @@ - 6.2 + 6.4 Index: openide/awt/src/org/netbeans/modules/openide/awt/DefaultAWTBridge.java =================================================================== RCS file: /cvs/openide/awt/src/org/netbeans/modules/openide/awt/DefaultAWTBridge.java,v retrieving revision 1.2 diff -u -r1.2 DefaultAWTBridge.java --- openide/awt/src/org/netbeans/modules/openide/awt/DefaultAWTBridge.java 21 Aug 2003 09:21:35 -0000 1.2 +++ openide/awt/src/org/netbeans/modules/openide/awt/DefaultAWTBridge.java 13 Jul 2005 12:54:08 -0000 @@ -17,6 +17,7 @@ import javax.swing.Action; import javax.swing.JMenuItem; import org.openide.awt.Actions; +import org.openide.awt.DynamicMenuContent; import org.openide.util.actions.BooleanStateAction; import org.openide.util.actions.SystemAction; @@ -64,6 +65,13 @@ public javax.swing.JPopupMenu createEmptyPopup() { return new org.openide.awt.JPopupMenuPlus (); - } + } + + public Component[] convertComponents(Component comp) { + if (comp instanceof DynamicMenuContent) { + return ((DynamicMenuContent)comp).getMenuPresenters(); + } + return new Component[] {comp}; + } } Index: openide/awt/src/org/openide/awt/Actions.java =================================================================== RCS file: /cvs/openide/awt/src/org/openide/awt/Actions.java,v retrieving revision 1.2 diff -u -r1.2 Actions.java --- openide/awt/src/org/openide/awt/Actions.java 29 Apr 2005 08:04:38 -0000 1.2 +++ openide/awt/src/org/openide/awt/Actions.java 13 Jul 2005 12:54:08 -0000 @@ -12,8 +12,8 @@ */ package org.openide.awt; +import java.util.List; import org.openide.ErrorManager; -import org.openide.awt.Mnemonics; import org.openide.util.HelpCtx; import org.openide.util.Lookup; import org.openide.util.Utilities; @@ -26,8 +26,7 @@ import java.beans.*; import java.lang.ref.WeakReference; - -import java.util.HashMap; +import java.util.ArrayList; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; @@ -126,10 +125,10 @@ public static void connect(JMenuItem item, Action action, boolean popup) { Bridge b = new MenuBridge(item, action, popup); - // Would make more sense to defer this until addNotify, but for some reason (why?) - // if you do that, various menus start out compacted and poorly painted. + if (item instanceof Actions.MenuItem) { + ((Actions.MenuItem)item).setBridge(b); + } b.updateState(null); - if (!popup) { // #39508 fix. setMenuActionConnection(item, action); @@ -349,12 +348,8 @@ * @param action the action to update */ static void updateKey(JMenuItem item, Action action) { - if (item instanceof SubMenu || !(item instanceof JMenu)) { - if (item instanceof SubMenu && !((SubMenu) item).useAccel()) { - item.setAccelerator(null); - } else { - item.setAccelerator((KeyStroke) action.getValue(Action.ACCELERATOR_KEY)); - } + if (!(item instanceof JMenu)) { + item.setAccelerator((KeyStroke) action.getValue(Action.ACCELERATOR_KEY)); } } @@ -937,34 +932,47 @@ } } - /** Sub menu bridge. + + /** The class that listens to the menu item selections and forwards it to the + * action class via the performAction() method. + */ + private static class ISubActionListener implements java.awt.event.ActionListener { + int index; + SubMenuModel support; + + public ISubActionListener(int index, SubMenuModel support) { + this.index = index; + this.support = support; + } + + /** called when a user clicks on this menu item */ + public void actionPerformed(ActionEvent e) { + support.performActionAt(index); + } + } + + /** Sub menu bridge 2. */ - private static final class SubMenuBridge extends MenuBridge implements ChangeListener { + private static final class SubMenuBridge extends MenuBridge implements ChangeListener, DynamicMenuContent { /** model to obtain subitems from */ private SubMenuModel model; - - /** submenu */ - private SubMenu menu; - + private List currentOnes; + private JMenuItem single; + private JMenu multi; /** Constructor. */ - public SubMenuBridge(SubMenu item, Action action, SubMenuModel model, boolean popup) { - super(item, action, popup); - prepareMargins(item, action); - - menu = item; + public SubMenuBridge(JMenuItem one, JMenu more, Action action, SubMenuModel model, boolean popup) { + super(one, action, popup); + single = one; + multi = more; + setMenuText(multi, (String)action.getValue(Action.NAME), popup); + prepareMargins(one, action); + prepareMargins(more, action); + currentOnes = new ArrayList(); this.model = model; - } - - public void addNotify() { - super.addNotify(); - model.addChangeListener(this); - generateSubMenu(); - } - - public void removeNotify() { - model.removeChangeListener(this); - super.removeNotify(); + single.addActionListener(new ISubActionListener(0, model)); +// model.addChangeListener(this); +// checkVisibility(); } /** Called when model changes. Regenerates the model. @@ -974,97 +982,81 @@ if (!EventQueue.isDispatchThread()) { new IllegalStateException("This must happen in the event thread!").printStackTrace(); } - // change in keys or in submenu model - generateSubMenu(); +// checkVisibility(); } + + public void updateState(String changedProperty) { + super.updateState(changedProperty); +// checkVisibility(); + } - /** Regenerates the menu - */ - private void generateSubMenu() { - boolean shouldUpdate = false; - - try { - menu.removeAll(); - - int cnt = model.getCount(); - - if (cnt != menu.previousCount) { - // update UI - shouldUpdate = true; - } - - // in all cases remeber the previous - menu.previousCount = cnt; - - // remove if there is an previous listener - if (menu.oneItemListener != null) { - menu.removeActionListener(menu.oneItemListener); - } - - if (cnt == 0) { - // menu disabled - menu.setEnabled(false); - - if (menu.oneItemListener != null) { - menu.removeActionListener(menu.oneItemListener); - menu.oneItemListener = null; - } - - return; - } else { - menu.setEnabled(true); - - // go on - } - - if (cnt == 1) { - // generate without submenu - menu.addActionListener(menu.oneItemListener = new ISubActionListener(0, model)); - - HelpCtx help = model.getHelpCtx(0); - associateHelp(menu, (help == null) ? findHelp(action) : help); - } else { - boolean addSeparator = false; - int count = model.getCount(); - - for (int i = 0; i < count; i++) { - String label = model.getLabel(i); - - // MenuShortcut shortcut = support.getMenuShortcut(i); - if (label == null) { - addSeparator = menu.getItemCount() > 0; - } else { - if (addSeparator) { - menu.addSeparator(); - addSeparator = false; - } - - // if (shortcut == null) - // (Dafe) changed to support mnemonics in item labels - JMenuItem item = new JMenuItem(); - Mnemonics.setLocalizedText(item, label); - - // attach the shortcut to the first item - if (i == 0) { - updateKey(item, action); - } - - item.addActionListener(new ISubActionListener(i, model)); - - HelpCtx help = model.getHelpCtx(i); - associateHelp(item, (help == null) ? findHelp(action) : help); - menu.add(item); + + + public JComponent[] getMenuPresenters() { + return synchMenuPresenters(null); + } + + public JComponent[] synchMenuPresenters(JComponent[] items) { + currentOnes.clear(); + int cnt = model.getCount(); + + if (cnt == 0) { + updateState(null); + currentOnes.add(single); + // menu disabled + single.setEnabled(false); + } else if (cnt == 1) { + updateState(null); + currentOnes.add(single); + single.setEnabled(true); + // generate without submenu + HelpCtx help = model.getHelpCtx(0); + associateHelp(single, (help == null) ? findHelp(action) : help); + } else { + currentOnes.add(multi); + multi.removeAll(); + //TODO + Mnemonics.setLocalizedText(multi, (String)action.getValue(Action.NAME)); + + boolean addSeparator = false; + int count = model.getCount(); + + for (int i = 0; i < count; i++) { + String label = model.getLabel(i); + + // MenuShortcut shortcut = support.getMenuShortcut(i); + if (label == null) { + addSeparator = multi.getItemCount() > 0; + } else { + if (addSeparator) { + multi.addSeparator(); + addSeparator = false; + } + + // if (shortcut == null) + // (Dafe) changed to support mnemonics in item labels + JMenuItem item = new JMenuItem(); + Mnemonics.setLocalizedText(item, label); + + // attach the shortcut to the first item + if (i == 0) { + updateKey(item, action); } + + item.addActionListener(new ISubActionListener(i, model)); + + HelpCtx help = model.getHelpCtx(i); + associateHelp(item, (help == null) ? findHelp(action) : help); + multi.add(item); } - - associateHelp(menu, findHelp(action)); - } - } finally { - if (shouldUpdate) { - menu.updateUI(); + + associateHelp(multi, findHelp(action)); } + multi.setEnabled(true); } + return (JMenuItem[])currentOnes.toArray(new JMenuItem[currentOnes.size()]); + } private void associateHelp(JComponent comp, HelpCtx help) { @@ -1074,26 +1066,7 @@ HelpCtx.setHelpIDString(comp, null); } } - - /** The class that listens to the menu item selections and forwards it to the - * action class via the performAction() method. - */ - private static class ISubActionListener implements java.awt.event.ActionListener { - int index; - SubMenuModel support; - - public ISubActionListener(int index, SubMenuModel support) { - this.index = index; - this.support = support; - } - - /** called when a user clicks on this menu item */ - public void actionPerformed(ActionEvent e) { - support.performActionAt(index); - } - } } - // // // The presenter classes @@ -1104,9 +1077,9 @@ * Extension of Swing menu item with connection to * system actions. */ - public static class MenuItem extends javax.swing.JMenuItem { + public static class MenuItem extends javax.swing.JMenuItem implements DynamicMenuContent { static final long serialVersionUID = -21757335363267194L; - + private Actions.Bridge bridge; /** Constructs a new menu item with the specified label * and no keyboard shortcut and connects it to the given SystemAction. * @param aAction the action to which this menu item should be connected @@ -1124,6 +1097,22 @@ public MenuItem(Action aAction, boolean useMnemonic) { Actions.connect(this, aAction, !useMnemonic); } + + void setBridge(Actions.Bridge br) { + bridge = br; + } + + public JComponent[] synchMenuPresenters(JComponent[] items) { + return getMenuPresenters(); + } + + public JComponent[] getMenuPresenters() { + if (bridge != null) { + bridge.updateState(null); + } + return new JComponent[] {this}; + } + } /** CheckboxMenuItem extends the java.awt.CheckboxMenuItem and adds @@ -1207,25 +1196,14 @@ return this.getPreferredSize(); } } + /** SubMenu provides easy way of displaying submenu items based on * SubMenuModel. */ - public static class SubMenu extends org.openide.awt.JMenuPlus { + public static class SubMenu extends JMenu implements DynamicMenuContent { static final long serialVersionUID = -4446966671302959091L; - /** number of previous sub items */ - int previousCount = -1; - - /** listener to remove from this menu or null */ - ActionListener oneItemListener; - - /** The keystroke which acts as the menu's accelerator. - * This menu can have an accelerator! */ - private KeyStroke accelerator; - - /** The model of the submenu used in menuitem generation */ - private SubMenuModel subModel; private SubMenuBridge bridge; /** Constructs a new ActMenuItem with the specified label @@ -1257,160 +1235,22 @@ * @param popup whether this is a popup menu */ public SubMenu(Action aAction, SubMenuModel model, boolean popup) { - subModel = model; - bridge = new SubMenuBridge(this, aAction, model, popup); + bridge = new SubMenuBridge(new JMenuItem(), this, aAction, model, popup); // set at least the name to have reasonable bounds bridge.updateState(Action.NAME); } - - // Fixes #26619 - - /** Overriden to finish initialization of the bridge on demand - */ - public void addNotify() { - super.addNotify(); - bridge.updateState(null); - - // Empty SubMenu -> disable - if (subModel.getCount() == 0) { - setEnabled(false); - } - } - - // XXX Overriding processKeyBinding is not a nice solution, used as - // a last resort here to fix the bug. - // #9331. Missed accelerator for Paste action. - - /** Overrides superclass method. - * If it has accelerator delegates processing of it to the first item. */ - protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { - // If it is as accelerator process the doClick binding to the - // first sub-item. - if (ks.equals(accelerator)) { - // Use first item if there is one. - Component[] cs = getMenuComponents(); - - if ((cs.length > 0) && cs[0] instanceof JComponent) { - JComponent comp = (JComponent) cs[0]; - - ActionMap am = comp.getActionMap(); - - if ((am != null) && comp.isEnabled()) { - Action action = am.get("doClick"); // NOI18N - - if (action != null) { - return SwingUtilities.notifyAction(action, ks, e, comp, e.getModifiers()); - } - } - - return false; - } - } - - return super.processKeyBinding(ks, e, condition, pressed); - } - - // XXX #11048. Ugly patch. - // This works for the cases when this menu is in 'menu' - // (not popup), the popup is handled by NbPopupMenuUI hack. This same - // method for popup wouldn't work since NbPopupMenuUI automatically - // passes focus to sub-menu. - - /** Overrides superclass method. Adds a hack for KB menu invokation - * when this JMenu needs to act like JMenuItem. */ - public void processKeyEvent(KeyEvent e, MenuElement[] path, MenuSelectionManager m) { - if ( - (getMenuComponentCount() <= 1) && - java.util.Arrays.equals(path, MenuSelectionManager.defaultManager().getSelectedPath()) && - ((e.getKeyCode() == KeyEvent.VK_ENTER) || (e.getKeyCode() == KeyEvent.VK_SPACE)) - ) { - ActionListener ac = oneItemListener; - - if (ac != null) { - m.setSelectedPath(new MenuElement[0]); - ac.actionPerformed(new ActionEvent(e.getSource(), 0, null)); - - return; - } - } - - super.processKeyEvent(e, path, m); - } - - /** Request for either MenuUI or MenuItemUI if the only one subitem should not - * use submenu. - */ - public String getUIClassID() { - if (previousCount == 0) { - return "MenuItemUI"; // NOI18N - } - - return (previousCount == 1) ? "MenuItemUI" : "MenuUI"; // NOI18N - } - - boolean useAccel() { - return subModel.getCount() <= 1; - } - - /** Overrides superclass method to be able to have an accelerator. */ - public void setAccelerator(KeyStroke keyStroke) { - KeyStroke oldAccelerator = accelerator; - this.accelerator = keyStroke; - - // Note: "accelerator" for the bean prop, not Action.ACCELERATOR_KEY == "AcceleratorKey" - firePropertyChange("accelerator", oldAccelerator, accelerator); // NOI18N - } - - /** Overrides superclass method to be able to have an accelerator. */ - public KeyStroke getAccelerator() { - return this.accelerator; - } - - public void menuSelectionChanged(boolean isIncluded) { - if (previousCount <= 1) { - setArmed(isIncluded); // JMenuItem behaviour - } else { - if (isArmed() && !isIncluded) { - setArmed(false); - } - - super.menuSelectionChanged(isIncluded); - } - } - - /** Menu cannot be selected when it represents MenuItem. - */ - public void setSelected(boolean s) { - // disabled menu cannot be selected - if (isEnabled() || !s) { - super.setSelected(s); - } - } - - /** Seting menu to disabled also sets the item as not selected - */ - public void setEnabled(boolean e) { - super.setEnabled(e); - - if (!e) { - super.setSelected(false); - } - } - - public void doClick(int pressTime) { - if (!isEnabled()) { - // do nothing if not enabled - return; - } - - if (oneItemListener != null) { - oneItemListener.actionPerformed(null); - } else { - super.doClick(pressTime); - } + + public JComponent[] getMenuPresenters() { + return bridge.getMenuPresenters(); + } + + public JComponent[] synchMenuPresenters(JComponent[] items) { + return bridge.synchMenuPresenters(items); } + } + private static class DisabledButtonFilter extends RGBImageFilter { DisabledButtonFilter() { Index: openide/awt/src/org/openide/awt/JInlineMenu.java =================================================================== RCS file: /cvs/openide/awt/src/org/openide/awt/JInlineMenu.java,v retrieving revision 1.1 diff -u -r1.1 JInlineMenu.java --- openide/awt/src/org/openide/awt/JInlineMenu.java 21 Apr 2005 20:12:29 -0000 1.1 +++ openide/awt/src/org/openide/awt/JInlineMenu.java 13 Jul 2005 12:54:08 -0000 @@ -23,31 +23,32 @@ import javax.swing.*; import javax.swing.event.*; +import org.openide.awt.DynamicMenuContent; +import org.openide.util.actions.Presenter; /** * Menu element that can contain other menu items. These items are then - * displayed "inline". The JInlineMenu can be used to componse more menu items + * displayed "inline". The JInlineMenu can be used to compose more menu items * into one that can be added/removed at once. * - * @deprecated JInlineMenu is resizing itself after being displayed, this - * behavior causes a lot of troubles for Swing/AWT on various platforms. Very - * hard to be fixed. Module developers should stop using this class. + * @deprecated since 6.5 JInlineMenu is a simple implementation of DynamicMenuContent, it + * doesn't update when visible and doesn't handle the separators itself anymore. * * @author Jan Jancura */ -public class JInlineMenu extends JMenuItem { +public class JInlineMenu extends JMenuItem implements DynamicMenuContent { /** generated Serialized Version UID */ static final long serialVersionUID = -2310488127953523571L; private static final Icon BLANK_ICON = new ImageIcon( Utilities.loadImage("org/openide/resources/actions/empty.gif") ); // NOI18N - /** north separator */ - private JSeparator north = new JSeparator(); - - /** south separator */ - private JSeparator south = new JSeparator(); +// /** north separator */ +// private JSeparator north = new JSeparator(); +// +// /** south separator */ +// private JSeparator south = new JSeparator(); /** Stores inner MenuItems added to outer menu. */ private JComponent[] items = new JComponent[0]; @@ -96,36 +97,36 @@ alignItems(); - // tell the parent it is not up-to-date as well - Container parent = getParent(); - - while (parent instanceof JInlineMenu) { - ((JInlineMenu) parent).upToDate = false; - parent = parent.getParent(); - } - - if (isShowing()) { // Ugly thing have happened - we're already visible - SwingUtilities.invokeLater(new Updater()); - } - } - - /* This method is overriden so that this class now allow following - * pattern to be used: - * - * (1) nm = new JInlineMenu(); - * (2) nm.setMenuItems( ... some items ... ); - * (3) myJPopupMenu.add(nm); - * - * While the old source required (1) (3) and (2) - */ - public void addNotify() { // addNotify it quite late to do anything, but we'll try - super.addNotify(); - - if (!upToDate) { - //System.err.println("InvokeLater-ing from addNotify()"); - SwingUtilities.invokeLater(new Updater()); - } - } +// // tell the parent it is not up-to-date as well +// Container parent = getParent(); +// +// while (parent instanceof JInlineMenu) { +// ((JInlineMenu) parent).upToDate = false; +// parent = parent.getParent(); +// } +// +// if (isShowing()) { // Ugly thing have happened - we're already visible +// SwingUtilities.invokeLater(new Updater()); +// } + } + +// /* This method is overriden so that this class now allow following +// * pattern to be used: +// * +// * (1) nm = new JInlineMenu(); +// * (2) nm.setMenuItems( ... some items ... ); +// * (3) myJPopupMenu.add(nm); +// * +// * While the old source required (1) (3) and (2) +// */ +// public void addNotify() { // addNotify it quite late to do anything, but we'll try +// super.addNotify(); +//// we for sure don't want to update menu when it's visible, it's evil. +//// if (!upToDate) { +//// //System.err.println("InvokeLater-ing from addNotify()"); +//// SwingUtilities.invokeLater(new Updater()); +//// } +// } /** Overriden to return first non null icon of current items or null if * all items has null icons. @@ -165,99 +166,99 @@ } } - static void prepareItemsInContainer(Container c) { - Component[] comps = c.getComponents(); - - for (int i = 0; i < comps.length; i++) { - if (comps[i] instanceof JInlineMenu) { - ((JInlineMenu) comps[i]).doUpdate(); - } - } - } - - private void doUpdate() { - // Let the subclasses add their own update logic, done this - // way because we want to go w/o API change for 3.4 on this topic - // when we're going to _solve_ this for 4.0 - Object prop = getClientProperty("hack.preShowUpdater"); - - if (prop instanceof Runnable) { - ((Runnable) prop).run(); - } - - updateContents(); - } - - /** This method is called only when in AWT, never in addNotify - * so it is safe to operate with the parent menu content */ - private void updateContents() { - Container parent = getParent(); - - if (!upToDate && (parent != null)) { - if (!(parent instanceof JInlineMenu)) { - // we're the highest JInlineMenu, do the update ourself - //call around all our subitems to prepare them - for (int i = 0; i < items.length; i++) { - Object prop = items[i].getClientProperty("hack.preShowUpdater"); - - if (prop instanceof Runnable) { - ((Runnable) prop).run(); - } - } - - removeItems(); - addItems(); - } - - upToDate = true; // we've been processed - } - } - - /** Remove all current items. - */ - private void removeItems() { - JComponent m = (JComponent) getParent(); - - if (m == null) { - return; // Can't happen - } - - if (m instanceof JInlineMenu) { - // Delegate removing to parent JInlineMenu. - ((JInlineMenu) m).removeItems(); - - return; - } - - // Remove all the items we've previously added. - if (addedItems != null) { - java.util.Iterator it = addedItems.iterator(); - - while (it.hasNext()) - m.remove((Component) it.next()); - } - - // Remove also our separators - m.remove(north); - m.remove(south); - - addedItems = null; - } - - /** Gets all inline items including inline items from - * sub-JInlineMenu's. Used only by parent - * JInlineMenu. */ - private void getAllInlineItems(List its) { - for (int i = 0; i < items.length; i++) { - Object item = items[i]; - - if (item instanceof JInlineMenu) { - ((JInlineMenu) item).getAllInlineItems(its); - } else { - its.add(item); - } - } - } +// static void prepareItemsInContainer(Container c) { +// Component[] comps = c.getComponents(); +// +// for (int i = 0; i < comps.length; i++) { +// if (comps[i] instanceof JInlineMenu) { +// ((JInlineMenu) comps[i]).doUpdate(); +// } +// } +// } + +// private void doUpdate() { +// // Let the subclasses add their own update logic, done this +// // way because we want to go w/o API change for 3.4 on this topic +// // when we're going to _solve_ this for 4.0 +// Object prop = getClientProperty("hack.preShowUpdater"); +// +// if (prop instanceof Runnable) { +// ((Runnable) prop).run(); +// } +// +// updateContents(); +// } +// +// /** This method is called only when in AWT, never in addNotify +// * so it is safe to operate with the parent menu content */ +// private void updateContents() { +// Container parent = getParent(); +// +// if (!upToDate && (parent != null)) { +// if (!(parent instanceof JInlineMenu)) { +// // we're the highest JInlineMenu, do the update ourself +// //call around all our subitems to prepare them +// for (int i = 0; i < items.length; i++) { +// Object prop = items[i].getClientProperty("hack.preShowUpdater"); +// +// if (prop instanceof Runnable) { +// ((Runnable) prop).run(); +// } +// } +// +// removeItems(); +// addItems(); +// } +// +// upToDate = true; // we've been processed +// } +// } + +// /** Remove all current items. +// */ +// private void removeItems() { +// JComponent m = (JComponent) getParent(); +// +// if (m == null) { +// return; // Can't happen +// } +// +// if (m instanceof JInlineMenu) { +// // Delegate removing to parent JInlineMenu. +// ((JInlineMenu) m).removeItems(); +// +// return; +// } +// +// // Remove all the items we've previously added. +// if (addedItems != null) { +// java.util.Iterator it = addedItems.iterator(); +// +// while (it.hasNext()) +// m.remove((Component) it.next()); +// } +// +// // Remove also our separators +// m.remove(north); +// m.remove(south); +// +// addedItems = null; +// } + +// /** Gets all inline items including inline items from +// * sub-JInlineMenu's. Used only by parent +// * JInlineMenu. */ +// private void getAllInlineItems(List its) { +// for (int i = 0; i < items.length; i++) { +// Object item = items[i]; +// +// if (item instanceof JInlineMenu) { +// ((JInlineMenu) item).getAllInlineItems(its); +// } else { +// its.add(item); +// } +// } +// } /** Finds the index of a component in array of components. * @return index or -1 @@ -274,100 +275,108 @@ return -1; } - void addItems() { - JComponent m = (JComponent) getParent(); - - if (m == null) { - return; // Can't happen - } - - boolean usedToBeContained = false; - - if (m instanceof JPopupMenu) { - usedToBeContained = JPopupMenuUtils.isPopupContained((JPopupMenu) m); - } - - // Get all items, including those ones from sub-JInlineMenu's. - List its = new java.util.ArrayList(items.length); - getAllInlineItems(its); - - JComponent[] items = (JComponent[]) its.toArray(new JComponent[its.size()]); - addedItems = its; - - // Find me please! - Component[] array = m.getComponents(); - - int menuPos = findIndex(this, array); - - if (menuPos == -1) { - return; // not found? strange! - } - - if ( - (menuPos > 0) && (items.length > 0) && (array.length > 0) && /* should be always true */ - !(array[menuPos - 1] instanceof JSeparator) && !(array[menuPos - 1] instanceof JInlineMenu) - ) { // not first and not after separator or another inline menu ==>> add separator before - m.add(north, menuPos++); - array = m.getComponents(); - } - - if (menuPos < (array.length - 1)) { - // not last - if ( - (items.length > 0) && !(array[menuPos + 1] instanceof JPopupMenu.Separator) && - !(array[menuPos + 1] instanceof JSeparator) - ) { - // adding non-zero items and not before separator - m.add(south, menuPos + 1); - } else if ( - (items.length == 0) && - (array[menuPos + 1] instanceof JPopupMenu.Separator || array[menuPos + 1] instanceof JSeparator) - ) { - // adding zero items and there is an extra separator after the JInlineMenu item ==>> remove it - m.remove(menuPos + 1); - array = m.getComponents(); - } - } - - // Add components to outer menu. - if (menuPos > array.length) { - int menuLength = items.length; - - for (int i = 0; i < menuLength; i++) { - m.add(items[i]); - } - } else { - int menuLength = items.length; - - for (int i = 0; i < menuLength; i++) { - m.add(items[i], ++menuPos); - - // advance menuPos for JInlineMenu - // otherwise the next item will be - // actually placed before expanded - // items of this JInlineMenu - if (items[i] instanceof JInlineMenu) { - JInlineMenu him = (JInlineMenu) items[i]; - menuPos += him.items.length; - } - } - } - - if (m instanceof JPopupMenu && m.isShowing()) { - // This can happen when somebody call setMenuItems on visible - JPopupMenuUtils.dynamicChange((JPopupMenu) m, usedToBeContained); - } else { - // ensure correct preferred size computation - m.invalidate(); - } - } - - private class Updater implements Runnable { - Updater() { - } - - public void run() { - updateContents(); - } - } +// void addItems() { +// JComponent m = (JComponent) getParent(); +// +// if (m == null) { +// return; // Can't happen +// } +// +// boolean usedToBeContained = false; +// +// if (m instanceof JPopupMenu) { +// usedToBeContained = JPopupMenuUtils.isPopupContained((JPopupMenu) m); +// } +// +// // Get all items, including those ones from sub-JInlineMenu's. +// List its = new java.util.ArrayList(items.length); +// getAllInlineItems(its); +// +// JComponent[] items = (JComponent[]) its.toArray(new JComponent[its.size()]); +// addedItems = its; +// +// // Find me please! +// Component[] array = m.getComponents(); +// +// int menuPos = findIndex(this, array); +// +// if (menuPos == -1) { +// return; // not found? strange! +// } +// +// if ( +// (menuPos > 0) && (items.length > 0) && (array.length > 0) && /* should be always true */ +// !(array[menuPos - 1] instanceof JSeparator) && !(array[menuPos - 1] instanceof JInlineMenu) +// ) { // not first and not after separator or another inline menu ==>> add separator before +// m.add(north, menuPos++); +// array = m.getComponents(); +// } +// +// if (menuPos < (array.length - 1)) { +// // not last +// if ( +// (items.length > 0) && !(array[menuPos + 1] instanceof JPopupMenu.Separator) && +// !(array[menuPos + 1] instanceof JSeparator) +// ) { +// // adding non-zero items and not before separator +// m.add(south, menuPos + 1); +// } else if ( +// (items.length == 0) && +// (array[menuPos + 1] instanceof JPopupMenu.Separator || array[menuPos + 1] instanceof JSeparator) +// ) { +// // adding zero items and there is an extra separator after the JInlineMenu item ==>> remove it +// m.remove(menuPos + 1); +// array = m.getComponents(); +// } +// } +// +// // Add components to outer menu. +// if (menuPos > array.length) { +// int menuLength = items.length; +// +// for (int i = 0; i < menuLength; i++) { +// m.add(items[i]); +// } +// } else { +// int menuLength = items.length; +// +// for (int i = 0; i < menuLength; i++) { +// m.add(items[i], ++menuPos); +// +// // advance menuPos for JInlineMenu +// // otherwise the next item will be +// // actually placed before expanded +// // items of this JInlineMenu +// if (items[i] instanceof JInlineMenu) { +// JInlineMenu him = (JInlineMenu) items[i]; +// menuPos += him.items.length; +// } +// } +// } +// +// if (m instanceof JPopupMenu && m.isShowing()) { +// // This can happen when somebody call setMenuItems on visible +// JPopupMenuUtils.dynamicChange((JPopupMenu) m, usedToBeContained); +// } else { +// // ensure correct preferred size computation +// m.invalidate(); +// } +// } + + public JComponent[] synchMenuPresenters(JComponent[] items) { + return this.items; + } + + public JComponent[] getMenuPresenters() { + return items; + } + +// private class Updater implements Runnable { +// Updater() { +// } +// +// public void run() { +// updateContents(); +// } +// } } Index: openide/awt/src/org/openide/awt/JMenuPlus.java =================================================================== RCS file: /cvs/openide/awt/src/org/openide/awt/JMenuPlus.java,v retrieving revision 1.1 diff -u -r1.1 JMenuPlus.java --- openide/awt/src/org/openide/awt/JMenuPlus.java 21 Apr 2005 20:12:29 -0000 1.1 +++ openide/awt/src/org/openide/awt/JMenuPlus.java 13 Jul 2005 12:54:08 -0000 @@ -21,10 +21,11 @@ * It assures, that the popup menu gets placed inside visible screen area. * It also improves placement of popups in the case the subclass lazily changes * the content from getPopupMenu(). + * @deprecated doesn't do anything special anymore - since 6.5 */ public class JMenuPlus extends JMenu { static final long serialVersionUID = -7700146216422707913L; - private static final boolean NO_POPUP_PLACEMENT_HACK = Boolean.getBoolean("netbeans.popup.no_hack"); // NOI18N +// private static final boolean NO_POPUP_PLACEMENT_HACK = Boolean.getBoolean("netbeans.popup.no_hack"); // NOI18N public JMenuPlus() { this(""); // NOI18N @@ -38,106 +39,105 @@ getAccessibleContext().setAccessibleDescription(label); } - /** Overriden to provide better strategy for placing the JMenu on the screen. - * @param b a boolean value -- true to make the menu visible, false to hide it - */ - public void setPopupMenuVisible(boolean b) { - boolean isVisible = isPopupMenuVisible(); - - if (b != isVisible) { - if ((b == true) && isShowing()) { - // The order of calls is a provision for subclassers that - // change the content of the menu during getPopupMenu() - // We compute the origin later with properly filled popup - JPopupMenu popup = getPopupMenu(); - - // HACK[pnejedly]: Notify all the items in the menu we're going to show - JInlineMenu.prepareItemsInContainer(popup); - - // End of HACK - // HACK[mkleint]: Notify all the items in the menu we're going to show - // #40824 - when the text changes, it's too late to update in popup.show() (which triggers the updateState() in the MenuBridge. - Actions.prepareMenuBridgeItemsInContainer(popup); - - // End of HACK - if (NO_POPUP_PLACEMENT_HACK) { - Point p = super.getPopupMenuOrigin(); - getPopupMenu().show(this, p.x, p.y); - } else { - Point p = getPopupMenuOrigin(); - popup.show(this, p.x, p.y); - } - } else { - getPopupMenu().setVisible(false); - } - } - } - - /** Overriden to provide better strategy for placing the JMenu on the screen. - * - * @return a Point in the coordinate space of the menu instance - * which should be used as the origin of the JMenu's popup menu. - */ - protected Point getPopupMenuOrigin() { - int x = 0; - int y = 0; - JPopupMenu pm = getPopupMenu(); - Rectangle screenRect = JPopupMenuUtils.getScreenRect(); - Dimension s = getSize(); - Dimension pmSize = pm.getSize(); - int screenRight = screenRect.x + screenRect.width; - int screenBottom = screenRect.y + screenRect.height; - - // For the first time the menu is popped up, - // the size has not yet been initiated - if (pmSize.width == 0) { - pmSize = pm.getPreferredSize(); - } - - Point position = getLocationOnScreen(); - - Container parent = getParent(); - - if (parent instanceof JPopupMenu) { - // We are a submenu (pull-right) - // First determine x: - if ((position.x + s.width + pmSize.width) < screenRight) { - x = s.width; // Prefer placement to the right - } else { - x = 0 - pmSize.width; // Otherwise place to the left - } - - // Then the y: - if ((position.y + pmSize.height) < screenBottom) { - y = 0; // Prefer dropping down - } else { - y = s.height - pmSize.height; // Otherwise drop 'up' - } - } else { - // We are a toplevel menu (pull-down) - // First determine the x: - if ((position.x + pmSize.width) < screenRight) { - x = 0; // Prefer extending to right - } else { - x = s.width - pmSize.width; // Otherwise extend to left - } - - // Then the y: - if ((position.y + s.height + pmSize.height) < screenBottom) { - y = s.height; // Prefer dropping down - } else { - y = 0 - pmSize.height; // Otherwise drop 'up' - } - } - - if (y < -position.y) { - y = -position.y; - } - - if (x < -position.x) { - x = -position.x; - } - - return new Point(x, y); - } +// /** Overriden to provide better strategy for placing the JMenu on the screen. +// * @param b a boolean value -- true to make the menu visible, false to hide it +// */ +// public void setPopupMenuVisible(boolean b) { +// boolean isVisible = isPopupMenuVisible(); +// +// if (b != isVisible) { +// if ((b == true) && isShowing()) { +//// // The order of calls is a provision for subclassers that +//// // change the content of the menu during getPopupMenu() +//// // We compute the origin later with properly filled popup +// JPopupMenu popup = getPopupMenu(); +//// +//// // HACK[pnejedly]: Notify all the items in the menu we're going to show +//// JInlineMenu.prepareItemsInContainer(popup); +//// +//// // End of HACK +//// // HACK[mkleint]: Notify all the items in the menu we're going to show +//// // #40824 - when the text changes, it's too late to update in popup.show() (which triggers the updateState() in the MenuBridge. +//// Actions.prepareMenuBridgeItemsInContainer(popup); +// +// // End of HACK +//// if (NO_POPUP_PLACEMENT_HACK) { +// Point p = super.getPopupMenuOrigin(); +// popup.show(this, p.x, p.y); +//// } else { +//// Point p = getPopupMenuOrigin(popup); +//// popup.show(this, p.x, p.y); +//// } +// } else { +// getPopupMenu().setVisible(false); +// } +// } +// } + +// /** Overriden to provide better strategy for placing the JMenu on the screen. +// * +// * @return a Point in the coordinate space of the menu instance +// * which should be used as the origin of the JMenu's popup menu. +// */ +// protected Point getPopupMenuOrigin(JPopupMenu pm) { +// int x = 0; +// int y = 0; +// Rectangle screenRect = JPopupMenuUtils.getScreenRect(); +// Dimension s = getSize(); +// Dimension pmSize = pm.getSize(); +// int screenRight = screenRect.x + screenRect.width; +// int screenBottom = screenRect.y + screenRect.height; +// +// // For the first time the menu is popped up, +// // the size has not yet been initiated +// if (pmSize.width == 0) { +// pmSize = pm.getPreferredSize(); +// } +// +// Point position = getLocationOnScreen(); +// +// Container parent = getParent(); +// +// if (parent instanceof JPopupMenu) { +// // We are a submenu (pull-right) +// // First determine x: +// if ((position.x + s.width + pmSize.width) < screenRight) { +// x = s.width; // Prefer placement to the right +// } else { +// x = 0 - pmSize.width; // Otherwise place to the left +// } +// +// // Then the y: +// if ((position.y + pmSize.height) < screenBottom) { +// y = 0; // Prefer dropping down +// } else { +// y = s.height - pmSize.height; // Otherwise drop 'up' +// } +// } else { +// // We are a toplevel menu (pull-down) +// // First determine the x: +// if ((position.x + pmSize.width) < screenRight) { +// x = 0; // Prefer extending to right +// } else { +// x = s.width - pmSize.width; // Otherwise extend to left +// } +// +// // Then the y: +// if ((position.y + s.height + pmSize.height) < screenBottom) { +// y = s.height; // Prefer dropping down +// } else { +// y = 0 - pmSize.height; // Otherwise drop 'up' +// } +// } +// +// if (y < -position.y) { +// y = -position.y; +// } +// +// if (x < -position.x) { +// x = -position.x; +// } +// +// return new Point(x, y); +// } } Index: openide/awt/src/org/openide/awt/JPopupMenuPlus.java =================================================================== RCS file: /cvs/openide/awt/src/org/openide/awt/JPopupMenuPlus.java,v retrieving revision 1.1 diff -u -r1.1 JPopupMenuPlus.java --- openide/awt/src/org/openide/awt/JPopupMenuPlus.java 21 Apr 2005 20:12:30 -0000 1.1 +++ openide/awt/src/org/openide/awt/JPopupMenuPlus.java 13 Jul 2005 12:54:08 -0000 @@ -21,38 +21,38 @@ /** A subclass of JPopupMenu which ensures that the popup menus do * not stretch off the edges of the screen. - * + * @deprecated - doesn't do anything special anymore. (since 6.5) */ public class JPopupMenuPlus extends JPopupMenu { - private static final boolean NO_POPUP_PLACEMENT_HACK = Boolean.getBoolean("netbeans.popup.no_hack"); // NOI18N +// private static final boolean NO_POPUP_PLACEMENT_HACK = Boolean.getBoolean("netbeans.popup.no_hack"); // NOI18N public JPopupMenuPlus() { } - /* - * Override the show() method to ensure that the popup will be - * on the screen. - */ - public void show(Component invoker, int x, int y) { - if (isVisible()) { - return; - } - - // HACK[pnejedly]: Notify all the items in the menu we're going to show - JInlineMenu.prepareItemsInContainer(this); - - // End of HACK - if (NO_POPUP_PLACEMENT_HACK) { - super.show(invoker, x, y); - - return; - } - - Point p = new Point(x, y); - SwingUtilities.convertPointToScreen(p, invoker); - - Point newPt = JPopupMenuUtils.getPopupMenuOrigin(this, p); - SwingUtilities.convertPointFromScreen(newPt, invoker); - super.show(invoker, newPt.x, newPt.y); - } +// /* +// * Override the show() method to ensure that the popup will be +// * on the screen. +// */ +// public void show(Component invoker, int x, int y) { +// if (isVisible()) { +// return; +// } +// +//// // HACK[pnejedly]: Notify all the items in the menu we're going to show +//// JInlineMenu.prepareItemsInContainer(this); +// +// // End of HACK +// if (NO_POPUP_PLACEMENT_HACK) { +// super.show(invoker, x, y); +// +// return; +// } +// +// Point p = new Point(x, y); +// SwingUtilities.convertPointToScreen(p, invoker); +// +// Point newPt = JPopupMenuUtils.getPopupMenuOrigin(this, p); +// SwingUtilities.convertPointFromScreen(newPt, invoker); +// super.show(invoker, newPt.x, newPt.y); +// } } Index: openide/awt/src/org/openide/awt/JPopupMenuUtils.java =================================================================== RCS file: /cvs/openide/awt/src/org/openide/awt/JPopupMenuUtils.java,v retrieving revision 1.1 diff -u -r1.1 JPopupMenuUtils.java --- openide/awt/src/org/openide/awt/JPopupMenuUtils.java 21 Apr 2005 20:12:30 -0000 1.1 +++ openide/awt/src/org/openide/awt/JPopupMenuUtils.java 13 Jul 2005 12:54:11 -0000 @@ -42,7 +42,7 @@ private static boolean problem = false; private static RequestProcessor reqProc; private static RequestProcessor.Task task; - private static final boolean NO_POPUP_PLACEMENT_HACK = Boolean.getBoolean("netbeans.popup.no_hack"); // NOI18N +// private static final boolean NO_POPUP_PLACEMENT_HACK = Boolean.getBoolean("netbeans.popup.no_hack"); // NOI18N /* * Called when a visible menu has dynamically changed. Ensure that @@ -74,9 +74,9 @@ } if (!newPt.equals(p)) { - if (!NO_POPUP_PLACEMENT_HACK) { - popup.setLocation(newPt.x, newPt.y); - } +// if (!NO_POPUP_PLACEMENT_HACK) { +// popup.setLocation(newPt.x, newPt.y); +// } } if (usedToBeContained != willBeContained) { @@ -126,9 +126,9 @@ refreshPopup(popup); if (!newPt.equals(p)) { - if (!NO_POPUP_PLACEMENT_HACK) { - popup.setLocation(newPt.x, newPt.y); - } +// if (!NO_POPUP_PLACEMENT_HACK) { +// popup.setLocation(newPt.x, newPt.y); +// } } popup.setVisible(true); Index: openide/loaders/manifest.mf =================================================================== RCS file: /cvs/openide/loaders/manifest.mf,v retrieving revision 1.21 diff -u -r1.21 manifest.mf --- openide/loaders/manifest.mf 11 May 2005 14:50:10 -0000 1.21 +++ openide/loaders/manifest.mf 13 Jul 2005 12:54:11 -0000 @@ -1,5 +1,5 @@ Manifest-Version: 1.0 OpenIDE-Module: org.openide.loaders -OpenIDE-Module-Specification-Version: 5.4 +OpenIDE-Module-Specification-Version: 5.5 OpenIDE-Module-Localizing-Bundle: org/openide/loaders/Bundle.properties Index: openide/loaders/nbproject/project.xml =================================================================== RCS file: /cvs/openide/loaders/nbproject/project.xml,v retrieving revision 1.9 diff -u -r1.9 project.xml --- openide/loaders/nbproject/project.xml 4 Jun 2005 05:16:46 -0000 1.9 +++ openide/loaders/nbproject/project.xml 13 Jul 2005 12:54:11 -0000 @@ -22,7 +22,7 @@ - 6.2 + 6.4 @@ -62,7 +62,7 @@ - 6.2 + 6.5 @@ -78,7 +78,7 @@ - 6.2 + 6.3 Index: openide/loaders/src/org/openide/awt/MenuBar.java =================================================================== RCS file: /cvs/openide/loaders/src/org/openide/awt/MenuBar.java,v retrieving revision 1.12 diff -u -r1.12 MenuBar.java --- openide/loaders/src/org/openide/awt/MenuBar.java 7 Jul 2005 11:58:39 -0000 1.12 +++ openide/loaders/src/org/openide/awt/MenuBar.java 13 Jul 2005 12:54:15 -0000 @@ -15,11 +15,16 @@ import java.awt.Component; import java.awt.EventQueue; +import java.awt.Point; +import java.awt.event.*; import java.awt.event.KeyEvent; import java.io.*; import java.util.*; import javax.swing.*; import javax.swing.KeyStroke; +import javax.swing.MenuElement; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import org.openide.ErrorManager; import org.openide.loaders.*; @@ -368,20 +373,23 @@ } /** Menu based on the folder content whith lazy items creation. */ - private static class LazyMenu extends JMenuPlus implements NodeListener, Runnable { + private static class LazyMenu extends JMenu implements NodeListener, Runnable, ChangeListener { DataFolder master; boolean icon; MenuFolder slave; + DynaMenuModel dynaModel; /** Constructor. */ public LazyMenu(final DataFolder df, boolean icon) { master = df; this.icon = icon; + dynaModel = new DynaMenuModel(); // Listen for changes in Node's DisplayName/Icon Node n = master.getNodeDelegate (); n.addNodeListener (org.openide.nodes.NodeOp.weakNodeListener (this, n)); updateProps(); + getModel().addChangeListener(this); } @@ -461,14 +469,61 @@ public void childrenRemoved (NodeMemberEvent ev) {} public void childrenReordered(NodeReorderEvent ev) {} public void nodeDestroyed (NodeEvent ev) {} - - /** Overrides superclass method to lazy create popup. */ - public JPopupMenu getPopupMenu() { - doInitialize(); - return super.getPopupMenu(); + private boolean selected = false; + public void stateChanged(ChangeEvent event) { + if (selected) { + selected = false; + } else { + selected = true; + doInitialize(); + dynaModel.checkSubmenu(this); +// // The order of calls is a provision for subclassers that +// // change the content of the menu during getPopupMenu() +// // We compute the origin later with properly filled popup +// JPopupMenu popup = getPopupMenu(); +// +// // HACK[pnejedly]: Notify all the items in the menu we're going to show +// JInlineMenu.prepareItemsInContainer(popup); +// +// // End of HACK +// // HACK[mkleint]: Notify all the items in the menu we're going to show +// // #40824 - when the text changes, it's too late to update in popup.show() (which triggers the updateState() in the MenuBridge. +// Actions.prepareMenuBridgeItemsInContainer(popup); +// +//// slave = null; + } } + + /** Overriden to provide better strategy for placing the JMenu on the screen. + * @param b a boolean value -- true to make the menu visible, false to hide it + */ + public void setPopupMenuVisible(boolean b) { + boolean isVisible = isPopupMenuVisible(); + + if (b != isVisible) { + if ((b == true) && isShowing()) { + doInitialize(); + dynaModel.checkSubmenu(this); +// // The order of calls is a provision for subclassers that +// // change the content of the menu during getPopupMenu() +// // We compute the origin later with properly filled popup +// JPopupMenu popup = getPopupMenu(); +// +// // HACK[pnejedly]: Notify all the items in the menu we're going to show +// JInlineMenu.prepareItemsInContainer(popup); +// +// // End of HACK +// // HACK[mkleint]: Notify all the items in the menu we're going to show +// // #40824 - when the text changes, it's too late to update in popup.show() (which triggers the updateState() in the MenuBridge. +// Actions.prepareMenuBridgeItemsInContainer(popup); + + } + } + super.setPopupMenuVisible(b); + } + private void doInitialize() { if(slave == null) { slave = new MenuFolder(); // will do the tracking @@ -554,7 +609,7 @@ */ protected Object createInstance(InstanceCookie[] cookies) throws IOException, ClassNotFoundException { - JMenu m = LazyMenu.this; + LazyMenu m = LazyMenu.this; //synchronized (this) { // see #15917 - attachment from 2001/09/27 LinkedList cInstances = new LinkedList(); @@ -574,69 +629,7 @@ m.add(item); } - - // clear first - refresh the menu's content - boolean addSeparator = false; - // is menu with some ityem with icon or not - boolean isWithIcons = false; - Icon curIcon = null; - Iterator it = cInstances.iterator(); - List menuItems = new ArrayList(cInstances.size()); - while (it.hasNext()) { - Object obj = it.next(); - if (obj instanceof Presenter.Menu) { - obj = ((Presenter.Menu)obj).getMenuPresenter(); - } - - if (obj instanceof JMenuItem) { - if(addSeparator) { - menuItems.add(null); - addSeparator = false; - } - // check icon - if (!isWithIcons) { - curIcon = ((JMenuItem)obj).getIcon(); - if (curIcon != null) { - isWithIcons = true; - } - } - menuItems.add((JMenuItem)obj); - } else if (obj instanceof JSeparator) { - addSeparator = menuItems.size() > 0; - } else if (obj instanceof Action) { - if(addSeparator) { - menuItems.add(null); - addSeparator = false; - } - Action a = (Action)obj; - JMenuItem item = new JMenuItem(); - Actions.connect (item, a, false); - // check icon - if (!isWithIcons) { - curIcon = item.getIcon(); - if (curIcon != null) { - isWithIcons = true; - } - } - menuItems.add (item); - } - } - - if (isWithIcons) { - menuItems = alignVertically(menuItems); - } - - // fill menu with built items - JMenuItem curItem = null; - for (Iterator iter = menuItems.iterator(); iter.hasNext(); ) { - curItem = (JMenuItem)iter.next(); - if (curItem != null) { - m.add(curItem); - } else { - // null means separator - m.addSeparator(); - } - } + m.dynaModel.loadSubmenu(cInstances, m); return m; } @@ -664,4 +657,4 @@ } } -} +} \ No newline at end of file Index: openide/util/apichanges.xml =================================================================== RCS file: /cvs/openide/util/apichanges.xml,v retrieving revision 1.7 diff -u -r1.7 apichanges.xml --- openide/util/apichanges.xml 3 Jul 2005 13:39:00 -0000 1.7 +++ openide/util/apichanges.xml 13 Jul 2005 12:54:18 -0000 @@ -24,6 +24,28 @@ + DynamicMenuContent interface added + + + + + + In order to support MacOSX top menus and to fix problems with deprecated JInlineMenu, this new + interface was added that allows to handle dynamic content in +Presenter.Menu + and Presenter.Popup. + If the instance returned by Presenter.Menu/Popup is an instance of +DynamicMenuContent, it's methods are + consulted when creating/updating the menu. + + + + + + + + + Support for interruption of RequestProcessor tasks Index: openide/util/manifest.mf =================================================================== RCS file: /cvs/openide/util/manifest.mf,v retrieving revision 1.4 diff -u -r1.4 manifest.mf --- openide/util/manifest.mf 10 Jun 2005 16:14:59 -0000 1.4 +++ openide/util/manifest.mf 13 Jul 2005 12:54:18 -0000 @@ -1,5 +1,5 @@ Manifest-Version: 1.0 OpenIDE-Module: org.openide.util -OpenIDE-Module-Specification-Version: 6.3 +OpenIDE-Module-Specification-Version: 6.4 OpenIDE-Module-Localizing-Bundle: org/openide/util/Bundle.properties Index: openide/util/src/org/netbeans/modules/openide/util/AWTBridge.java =================================================================== RCS file: /cvs/openide/util/src/org/netbeans/modules/openide/util/AWTBridge.java,v retrieving revision 1.1 diff -u -r1.1 AWTBridge.java --- openide/util/src/org/netbeans/modules/openide/util/AWTBridge.java 21 Aug 2003 09:55:39 -0000 1.1 +++ openide/util/src/org/netbeans/modules/openide/util/AWTBridge.java 13 Jul 2005 12:54:18 -0000 @@ -58,6 +58,8 @@ public abstract Component createToolbarPresenter (Action action); + public abstract Component[] convertComponents(Component comp); + // // Default implementation of the the presenter // @@ -80,5 +82,8 @@ return new javax.swing.JPopupMenu (); } + public Component[] convertComponents(Component comp) { + return new Component[] {comp}; + } } } Index: openide/util/src/org/openide/util/Utilities.java =================================================================== RCS file: /cvs/openide/util/src/org/openide/util/Utilities.java,v retrieving revision 1.2 diff -u -r1.2 Utilities.java --- openide/util/src/org/openide/util/Utilities.java 26 Apr 2005 16:37:56 -0000 1.2 +++ openide/util/src/org/openide/util/Utilities.java 13 Jul 2005 12:54:22 -0000 @@ -12,19 +12,16 @@ */ package org.openide.util; +import javax.swing.JSeparator; +import org.netbeans.modules.openide.util.AWTBridge; import org.openide.ErrorManager; -import org.openide.util.ContextAwareAction; import org.openide.util.actions.Presenter; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.FocusListener; import java.awt.event.KeyEvent; -import java.beans.PropertyChangeListener; -import java.beans.VetoableChangeListener; - import java.io.BufferedReader; import java.io.File; import java.io.IOException; @@ -43,12 +40,12 @@ import java.util.List; import javax.swing.Action; +import javax.swing.JComponent; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.KeyStroke; import javax.swing.Timer; -import javax.swing.event.ChangeListener; -import javax.swing.event.DocumentListener; + /** Otherwise uncategorized useful static methods. @@ -2592,14 +2589,23 @@ ); // NOI18N ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, npe); } - - menu.add(item); } else { // We need to correctly handle mnemonics with '&' etc. - JMenuItem mi = org.netbeans.modules.openide.util.AWTBridge.getDefault().createPopupPresenter( + item = org.netbeans.modules.openide.util.AWTBridge.getDefault().createPopupPresenter( action ); - menu.add(mi); + } + Component[] comps = AWTBridge.getDefault().convertComponents(item); + for (int v = 0; v < comps.length;v++) { + if ((comps[v] == null || comps[v] instanceof JSeparator) && menu.getComponentCount() > 0 && menu.getComponent(menu.getComponentCount() - 1) instanceof JSeparator) { +// System.out.println("ignorring separator"); + } else { +// System.out.println("is not=" + comps[v].getClass()); + menu.add(comps[v]); + } + } + if (comps.length == 0 || (comps.length > 0 && comps[comps.length - 1] instanceof JSeparator)) { + haveHadNonSep = false; } } else { // Add next time it is needed. Index: openide/util/src/org/openide/util/actions/Presenter.java =================================================================== RCS file: /cvs/openide/util/src/org/openide/util/actions/Presenter.java,v retrieving revision 1.1 diff -u -r1.1 Presenter.java --- openide/util/src/org/openide/util/actions/Presenter.java 21 Apr 2005 20:16:15 -0000 1.1 +++ openide/util/src/org/openide/util/actions/Presenter.java 13 Jul 2005 12:54:22 -0000 @@ -38,8 +38,9 @@ */ public interface Menu extends Presenter { /** Get a menu item that can present this action in a {@link javax.swing.JMenu}. - * @return the representation for this action - */ + * If your menu content is dynamic in nature, consider using {@link org.openide.awt.DynamicMenuContent} + * @return the representation for this action + */ public JMenuItem getMenuPresenter(); } @@ -47,6 +48,7 @@ */ public interface Popup extends Presenter { /** Get a menu item that can present this action in a {@link javax.swing.JPopupMenu}. + * If your menu content is dynamic in nature, consider using {@link org.openide.awt.DynamicMenuContent} * @return the representation for this action */ public JMenuItem getPopupPresenter(); Index: openide/util/test/unit/src/org/openide/util/UtilitiesActionsTest.java =================================================================== RCS file: /cvs/openide/util/test/unit/src/org/openide/util/UtilitiesActionsTest.java,v retrieving revision 1.1 diff -u -r1.1 UtilitiesActionsTest.java --- openide/util/test/unit/src/org/openide/util/UtilitiesActionsTest.java 22 Apr 2005 06:03:06 -0000 1.1 +++ openide/util/test/unit/src/org/openide/util/UtilitiesActionsTest.java 13 Jul 2005 12:54:22 -0000 @@ -12,14 +12,17 @@ */ package org.openide.util; - -import java.lang.ref.*; +import java.awt.Component; +import javax.swing.AbstractAction; import javax.swing.Action; +import javax.swing.JComponent; import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; import junit.framework.*; import org.netbeans.junit.*; +import org.openide.util.actions.Presenter; /** Tests of actions related methods in Utilities class. */ Index: openide/www/proposals/actions/index.html =================================================================== RCS file: /cvs/openide/www/proposals/actions/index.html,v retrieving revision 1.22 diff -u -r1.22 index.html --- openide/www/proposals/actions/index.html 29 Apr 2005 00:27:43 -0000 1.22 +++ openide/www/proposals/actions/index.html 13 Jul 2005 12:54:23 -0000 @@ -88,6 +88,9 @@ activated nodes) [Implemented]
  • Actions that require more than one menu item should be able to achieve this in cleaner way than by usage of (now deprecated) org.openide.awt.JInlineMenu component +
    + SOLVED: Use org.openide.util.actions.DynamicMenuContent instead of the org.openide.awt.JInlineMenu +
  • All actions should update its state before a menu is shown to prevent resizing and dynamic updates of menu when visible (see Context) [Implemented]
  • It is not easy to change menu provided by another module Index: projects/projectui/nbproject/project.properties =================================================================== RCS file: /cvs/projects/projectui/nbproject/project.properties,v retrieving revision 1.6 diff -u -r1.6 project.properties --- projects/projectui/nbproject/project.properties 18 Apr 2005 22:17:13 -0000 1.6 +++ projects/projectui/nbproject/project.properties 13 Jul 2005 12:54:25 -0000 @@ -9,7 +9,7 @@ # Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun # Microsystems, Inc. All Rights Reserved. -spec.version.base=1.5.0 +spec.version.base=1.5.1 javadoc.arch=${basedir}/arch.xml Index: projects/projectui/nbproject/project.xml =================================================================== RCS file: /cvs/projects/projectui/nbproject/project.xml,v retrieving revision 1.18 diff -u -r1.18 project.xml --- projects/projectui/nbproject/project.xml 4 Jun 2005 05:16:58 -0000 1.18 +++ projects/projectui/nbproject/project.xml 13 Jul 2005 12:54:25 -0000 @@ -84,7 +84,7 @@ - 6.2 + 6.4 @@ -116,7 +116,7 @@ - 6.2 + 6.5 Index: projects/projectui/src/org/netbeans/modules/project/ui/actions/RecentProjects.java =================================================================== RCS file: /cvs/projects/projectui/src/org/netbeans/modules/project/ui/actions/RecentProjects.java,v retrieving revision 1.11 diff -u -r1.11 RecentProjects.java --- projects/projectui/src/org/netbeans/modules/project/ui/actions/RecentProjects.java 14 Apr 2005 14:26:38 -0000 1.11 +++ projects/projectui/src/org/netbeans/modules/project/ui/actions/RecentProjects.java 13 Jul 2005 12:54:25 -0000 @@ -22,7 +22,9 @@ import java.util.Iterator; import java.util.List; import javax.swing.AbstractAction; +import javax.swing.Action; import javax.swing.ImageIcon; +import javax.swing.JComponent; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.event.PopupMenuEvent; @@ -37,6 +39,7 @@ import org.openide.nodes.Node; import org.openide.util.NbBundle; import org.openide.util.Utilities; +import org.openide.awt.DynamicMenuContent; import org.openide.util.actions.Presenter; import org.openide.filesystems.FileChangeAdapter; import org.openide.filesystems.FileEvent; @@ -84,7 +87,7 @@ } private JMenu createSubMenu() { - JMenu menu = new JMenu(this); + JMenu menu = new UpdatingMenu(this); menu.setMnemonic(NbBundle.getMessage(RecentProjects.class, "MNE_RecentProjectsAction_Name").charAt(0)); return menu; } @@ -208,6 +211,23 @@ private class ProjectDirListener extends FileChangeAdapter { public void fileDeleted(FileEvent fe) { recreate = true; + } + } + + private class UpdatingMenu extends JMenu implements DynamicMenuContent { + + public UpdatingMenu(Action action) { + super(action); + } + + public JComponent[] synchMenuPresenters(JComponent[] items) { + fillSubMenu(this); + recreate = false; + return getMenuPresenters(); + } + + public JComponent[] getMenuPresenters() { + return new JComponent[] { this }; } } Index: xtest/instance/master-config.xml =================================================================== RCS file: /cvs/xtest/instance/master-config.xml,v retrieving revision 1.155 diff -u -r1.155 master-config.xml --- xtest/instance/master-config.xml 11 Jul 2005 12:30:30 -0000 1.155 +++ xtest/instance/master-config.xml 13 Jul 2005 12:55:42 -0000 @@ -23,6 +23,7 @@ +