Source code: org/gjt/sp/jedit/menu/EnhancedMenu.java
1 /*
2 * EnhancedMenu.java - jEdit menu
3 * :tabSize=8:indentSize=8:noTabs=false:
4 * :folding=explicit:collapseFolds=1:
5 *
6 * Copyright (C) 2001, 2003 Slava Pestov
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23 package org.gjt.sp.jedit.menu;
24
25 //{{{ Imports
26 import javax.swing.event.*;
27 import javax.swing.*;
28 import java.util.StringTokenizer;
29 import org.gjt.sp.jedit.msg.*;
30 import org.gjt.sp.jedit.*;
31 //}}}
32
33 public class EnhancedMenu extends JMenu implements MenuListener
34 {
35 //{{{ EnhancedMenu constructor
36 public EnhancedMenu(String name)
37 {
38 this(name,jEdit.getProperty(name.concat(".label")),
39 jEdit.getActionContext());
40 } //}}}
41
42 //{{{ EnhancedMenu constructor
43 public EnhancedMenu(String name, String label)
44 {
45 this(name,label,jEdit.getActionContext());
46 } //}}}
47
48 //{{{ EnhancedMenu constructor
49 public EnhancedMenu(String name, String label, ActionContext context)
50 {
51 this.context = context;
52 if(label == null)
53 label = name;
54
55 char mnemonic;
56 int index = label.indexOf('$');
57 if(index != -1 && label.length() - index > 1)
58 {
59 mnemonic = Character.toLowerCase(label.charAt(index + 1));
60 label = label.substring(0,index).concat(label.substring(++index));
61 }
62 else
63 mnemonic = '\0';
64
65 setText(label);
66 if(!OperatingSystem.isMacOS())
67 setMnemonic(mnemonic);
68
69 String menuItems = jEdit.getProperty(name);
70 if(menuItems != null)
71 {
72 StringTokenizer st = new StringTokenizer(menuItems);
73 while(st.hasMoreTokens())
74 {
75 String menuItemName = st.nextToken();
76 if(menuItemName.equals("-"))
77 addSeparator();
78 else
79 add(GUIUtilities.loadMenuItem(context,menuItemName,true));
80 }
81 }
82
83 initialComponentCount = getMenuComponentCount();
84
85 providerCode = jEdit.getProperty(name + ".code");
86
87 ebStub = new EditBusStub(name);
88 ebStub.menuOutOfDate = true;
89
90 addMenuListener(this);
91
92 if(providerCode != null)
93 EditBus.addToBus(ebStub);
94 } //}}}
95
96 //{{{ menuSelected() method
97 public void menuSelected(MenuEvent evt)
98 {
99 init();
100 } //}}}
101
102 public void menuDeselected(MenuEvent e) {}
103
104 public void menuCanceled(MenuEvent e) {}
105
106 //{{{ init() method
107 public void init()
108 {
109 if(providerCode == null)
110 return;
111
112 if(provider == null)
113 {
114 Object obj = BeanShell.eval(null,
115 BeanShell.getNameSpace(),
116 providerCode);
117 provider = (DynamicMenuProvider)obj;
118 }
119
120 if(provider == null)
121 {
122 // error
123 providerCode = null;
124 return;
125 }
126
127 if(ebStub.menuOutOfDate || provider.updateEveryTime())
128 {
129 ebStub.menuOutOfDate = false;
130
131 while(getMenuComponentCount() != initialComponentCount)
132 remove(getMenuComponentCount() - 1);
133
134 if(provider != null)
135 provider.update(this);
136 }
137 } //}}}
138
139 //{{{ Protected members
140 protected int initialComponentCount;
141 protected ActionContext context;
142
143 protected String providerCode;
144 protected DynamicMenuProvider provider;
145
146 protected EditBusStub ebStub;
147
148 //{{{ finalize() method
149 protected void finalize() throws Exception
150 {
151 if(ebStub != null)
152 EditBus.removeFromBus(ebStub);
153 } //}}}
154
155 //}}}
156
157 //{{{ EditBusStub class
158 /* EnhancedMenu has a reference to EditBusStub, but not the other
159 * way around. So when the EnhancedMenu is being garbage collected
160 * its finalize() method removes the EditBusStub from the edit bus. */
161 static class EditBusStub implements EBComponent
162 {
163 String name;
164 boolean menuOutOfDate;
165
166 EditBusStub(String name)
167 {
168 this.name = name;
169 menuOutOfDate = true;
170 }
171
172 public void handleMessage(EBMessage msg)
173 {
174 if(msg instanceof DynamicMenuChanged
175 && name.equals(((DynamicMenuChanged)msg)
176 .getMenuName()))
177 {
178 menuOutOfDate = true;
179 }
180 else if(msg instanceof PropertiesChanged)
181 {
182 // while this might be questionable, some
183 // menus depend on properties
184 menuOutOfDate = true;
185 }
186 }
187 } //}}}
188 }