001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.uml.ui.swing.drawingarea;
043:
044: import java.util.*;
045: import java.awt.*;
046: import java.awt.event.ActionListener;
047: import javax.swing.*;
048: import com.tomsawyer.util.TSSystem;
049: import com.tomsawyer.editor.TSELocalization;
050: import com.tomsawyer.editor.TSEImage;
051: import com.tomsawyer.editor.TSEGraphWindow;
052: import javax.swing.border.Border;
053: import org.netbeans.modules.uml.core.metamodel.diagrams.DiagramEnums;
054: import org.netbeans.modules.uml.resources.images.ImageUtil;
055:
056: public abstract class ADDrawingAreaResourceBundle extends
057: ListResourceBundle {
058:
059: Vector appButtons = new Vector(90, 10);
060:
061: ADParameterReader reader;
062:
063: ADDrawingAreaControl m_drawingArea;
064:
065: Hashtable radioControllers = new Hashtable(11, 0.9f);
066:
067: private AbstractButton defaultButton;
068: private HashMap layoutButtonMap = new HashMap<String, AbstractButton>();
069:
070: public void setDrawingArea(ADDrawingAreaControl pDrawingArea) {
071: this .m_drawingArea = pDrawingArea;
072: }
073:
074: /**
075: * This method returns the number of resources held in this
076: * resource bundle.
077: */
078: public int size() {
079: return (this .getContents().length);
080: }
081:
082: /**
083: * This method redefines the standard behavior of the <code>
084: * getObject</code> method of the ListResourceBundle class.
085: * Instead of throwing an exception, it returns null if the given
086: * resource is not found.
087: */
088: public Object getObjectResource(String key) {
089: Object value = null;
090:
091: try {
092: value = this .getObject(key);
093: } catch (MissingResourceException resourceError) {
094: }
095:
096: return (value);
097: }
098:
099: /**
100: * This method redefines the standard behavior of the <code>
101: * getString</code> method of the ListResourceBundle class.
102: * Instead of throwing an exception, it returns null if the given
103: * resource is not found.
104: */
105: public String getStringResource(String key) {
106: String value = null;
107:
108: if (this .reader != null) {
109: value = this .reader.getParameter(key);
110: }
111:
112: if (value == null) {
113: try {
114: value = this .getString(key);
115: } catch (MissingResourceException resourceError) {
116: }
117: }
118:
119: return (value);
120: }
121:
122: /**
123: * This method returns an icon resource from the resource bundle
124: * associated with the specified class. It returns null if the
125: * icon resource could not be loaded.
126: */
127: public ImageIcon getIconResource(String resourceName,
128: Class resourceClass) {
129: ImageIcon icon = null;
130:
131: String imagePath = this .getStringResource(resourceName);
132:
133: if (imagePath != null) {
134: Image image = TSEImage.loadImage(resourceClass, imagePath);
135:
136: if (image != null) {
137: icon = new ImageIcon(image);
138: }
139: }
140:
141: return (icon);
142: }
143:
144: /**
145: * This method returns the first field(key) of the resource table
146: * at the specified index.
147: */
148: public Object getKeyAt(int index) {
149: return (this .getContents()[index][0]);
150: }
151:
152: /**
153: * This method returns the second field(value) of the resource
154: * table at the specified index.
155: */
156: public Object getValueAt(int index) {
157: return (this .getContents()[index][1]);
158: }
159:
160: /**
161: * This method locates the first occurence of the resource
162: * starting with the specific name in the resource table. It
163: * returns the index of the resource in the table if it is found,
164: * and the length of the table plus 1 otherwise.
165: */
166: public int locate(String name) {
167: Object[][] resourceTable = this .getContents();
168:
169: // skip resources until the first item starting with the given
170: // name is found
171:
172: for (int index = 0; index < resourceTable.length; index++) {
173: String resource = (String) resourceTable[index][0];
174:
175: if (resource.startsWith(name)) {
176: return (index);
177: }
178: }
179:
180: return (resourceTable.length + 1);
181: }
182:
183: /**
184: * This method sets the parameter reader that provides access to
185: * the parameters that were re-specified at the execution time,
186: * rather than compile-time.
187: */
188: public void setParameterReader(ADParameterReader reader) {
189: this .reader = reader;
190: }
191:
192: // ---------------------------------------------------------------------
193: // Section: GUI building
194: // ---------------------------------------------------------------------
195:
196: /**
197: * This method creates a toolbar specified by a given name in the
198: * resource table. If the toolbar is not present, it returns null.
199: */
200: public JToolBar createToolBar(String name, ActionListener listener) {
201: // locate resources associated with the named toolbar
202: int index = this .locate(name);
203:
204: // if index is outside the legal range there is no such toolbar
205:
206: if (index >= this .size()) {
207: return (null);
208: }
209:
210: // OK, we have some resources; add toolbar items
211: JToolBar toolbar = new JToolBar();
212:
213: // set the floatable property of the toolbar
214: toolbar.setFloatable("true".equals(this .getStringResource(name
215: + ".floatable")));
216: Border b = (Border) UIManager.get("Nb.Editor.Toolbar.border"); //NOI18N
217: toolbar.setBorder(b);
218: // set the orientation of the toolbar: either vertical or horizontal
219: String orientation = this .getStringResource(name
220: + ".orientation");
221: if ("vertical".equals(orientation)) {
222: toolbar.setLayout(new BoxLayout(toolbar, BoxLayout.Y_AXIS));
223: }
224:
225: this .populateToolbar(toolbar, index + 1, listener);
226:
227: TSELocalization.setComponentOrientation(toolbar);
228:
229: return (toolbar);
230: }
231:
232: /**
233: * This method populates a toolbar with plain and toggle buttons.
234: * It returns the index of the last entry scanned in the resource
235: * table.
236: */
237: public int populateToolbar(JToolBar toolbar, int index,
238: ActionListener listener) {
239: String tooltipFormat = TSEGraphWindow.getToolTipFormat();
240: String type = (String) this .getKeyAt(index);
241: boolean needSeparator = false;
242:
243: while ("item".equals(type)) {
244: String name = (String) this .getValueAt(index);
245:
246: if ((name == null) || (name.length() <= 0)) {
247: needSeparator = true;
248: } else {
249: JComponent item = null;
250:
251: // implementation for zoom combo box
252: if (name.equals("zoom.comboBox")) {
253: JComboBox comboBox = this .m_drawingArea
254: .getZoomComboBox();
255: comboBox.addActionListener(listener);
256: item = comboBox;
257: } else {
258: AbstractButton button;
259:
260: // see if it is a radio or plain menu item
261: String group = this .getStringResource(name
262: + ".group");
263:
264: if (group != null) {
265: button = new JToggleButton();
266: this .getRadioController(group + ".button").add(
267: button);
268: String checked = this .getStringResource(name
269: + ".checked");
270: if ("true".equals(checked))
271: button.setSelected(true);
272:
273: } else {
274: // see if the item is to be checked
275: String checked = this .getStringResource(name
276: + ".checked");
277:
278: if (checked == null) {
279: /*Added by Smitha - Fix for bug# 6253669*/
280: // if(name.equals("main.showFriendly"))
281: // {
282: // button = new JToggleButton();
283: // }else
284: // {
285: button = new JButton();
286: // }
287: } else {
288: button = new JToggleButton();
289: button.setSelected("true".equals(checked));
290: }
291: }
292: if ("true".equals(getStringResource(name
293: + ".default")))
294: defaultButton = button;
295:
296: button.setRequestFocusEnabled(false);
297:
298: // since the button icons are 16x15 pixels add an extra
299: // pixel to the bottom pad.
300:
301: button.setMargin(new Insets(1, 1, 2, 1));
302:
303: // check if there is a command associated with the
304: // item. If there is the item gets a command listener.
305: // Otherwise disable it.
306:
307: String command = this .getStringResource(name
308: + ".command");
309:
310: if (command != null) {
311: button.setActionCommand(command);
312: button.addActionListener(listener);
313:
314: // only buttons with commands are remembered
315: this .appButtons.addElement(button);
316: } else {
317: button.setEnabled(false);
318: }
319:
320: ImageIcon icon = this .getIconResource(name
321: + ".icon.pressed", ImageUtil.class);
322:
323: icon = this .getIconResource(name + ".icon",
324: ImageUtil.class);
325:
326: if (icon != null) {
327: button.setIcon(icon);
328:
329: // This is a workaround for a Swing bug (ID 4363569)
330: // in JDK 1.3
331:
332: if (TSSystem.isJVM13()) {
333: ImageIcon disabledIcon = new ImageIcon(
334: GrayFilter.createDisabledImage(icon
335: .getImage()));
336:
337: button.setDisabledIcon(disabledIcon);
338: }
339: } else {
340: String text = this .getStringResource(name
341: + ".text");
342:
343: if (text != null) {
344: button.setText(text);
345: }
346: }
347:
348: item = button;
349: if ("layout".equals(group)) // NOI18N
350: {
351: layoutButtonMap.put(command, button);
352: }
353: }
354:
355: if (item != null) {
356: String tooltip = this .getStringResource(name
357: + ".tooltip");
358:
359: if (tooltip != null) {
360: if (TSSystem.isJVM13orAbove()) {
361: item.setToolTipText(TSSystem.replace(
362: tooltipFormat,
363: TSEGraphWindow.TOOLTIP_PLACEHOLDER,
364: tooltip));
365: } else {
366: item.setToolTipText(tooltip);
367: }
368: }
369:
370: if (needSeparator) {
371: toolbar.addSeparator();
372: needSeparator = false;
373: }
374: //Jyothi: Fix for Bug#6252914 - Tool bar menu: layout sequence diagram should be shown on sequence diagram only.
375: if ((m_drawingArea.getDiagramKind() != DiagramEnums.DK_SEQUENCE_DIAGRAM)
376: && (name
377: .equals("main.layout.layoutSequenceDiagram"))) {
378: //do NOT add item to the toolbar.. we don't want seqlayout button on non-seq diagrams
379: } else if ((m_drawingArea.getDiagramKind() == DiagramEnums.DK_SEQUENCE_DIAGRAM)
380: && ((name
381: .equals("main.layout.hierarchicalLayout"))
382: || (name
383: .equals("main.layout.orthogonalLayout"))
384: || (name
385: .equals("main.layout.symmetricLayout")) || (name
386: .equals("main.layout.incrementalLayout")))) {
387: //do NOT add the item to the toolbar -- we don't want other layout buttons on sequence diagram
388: } else {
389: toolbar.add(item);
390: }
391: }
392: }
393:
394: type = (String) this .getKeyAt(++index);
395: }
396:
397: return (index);
398: }
399:
400: /**
401: * This method returns an enumeration of all buttons created by
402: * this resource.
403: */
404: public Enumeration getAllButtons() {
405: return (this .appButtons.elements());
406: }
407:
408: /**
409: * This method returns the button group controller with a given
410: * name. It returns null if it cannot find one.
411: */
412: public ButtonGroup getRadioController(String name) {
413: ButtonGroup group = (ButtonGroup) this .radioControllers
414: .get(name);
415:
416: if (group == null) {
417: group = new ButtonGroup();
418: this .radioControllers.put(name, group);
419: }
420:
421: return (group);
422: }
423:
424: public void setDefault() {
425: if (defaultButton != null)
426: defaultButton.setSelected(true);
427: }
428:
429: public void setLayoutStyle(int style) {
430: String command = ADDrawingAreaConstants.APPLY_LAYOUT + "."
431: + style;
432: AbstractButton button = (AbstractButton) layoutButtonMap
433: .get(command);
434: if (button != null && !button.isSelected())
435: button.setSelected(true);
436: }
437:
438: void clearDrawingAreaControlRefs() {
439: setParameterReader(null);
440: setDrawingArea(null);
441: appButtons = new Vector(90, 10);
442: defaultButton = null;
443: layoutButtonMap = new HashMap<String, AbstractButton>();
444: }
445: }
|