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-2006 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.vmd.midp.propertyeditors;
043:
044: import java.awt.GridLayout;
045: import java.awt.event.ItemEvent;
046: import java.awt.event.ItemListener;
047: import java.util.ArrayList;
048: import java.util.Collections;
049: import java.util.HashMap;
050: import java.util.List;
051: import java.util.Map;
052: import javax.swing.BorderFactory;
053: import javax.swing.ButtonGroup;
054: import javax.swing.JCheckBox;
055: import javax.swing.JComponent;
056: import javax.swing.JPanel;
057: import javax.swing.JRadioButton;
058: import javax.swing.JToggleButton;
059: import org.netbeans.modules.vmd.api.model.DesignComponent;
060: import org.netbeans.modules.vmd.api.model.PropertyValue;
061: import org.netbeans.modules.vmd.api.model.TypeID;
062: import org.netbeans.modules.vmd.midp.components.MidpTypes;
063: import org.netbeans.modules.vmd.midp.components.general.Bitmask.BitmaskItem;
064: import org.netbeans.modules.vmd.midp.components.items.ItemCD;
065: import org.netbeans.modules.vmd.midp.components.items.ItemLayouts;
066: import org.netbeans.modules.vmd.midp.propertyeditors.api.usercode.PropertyEditorElement;
067: import org.netbeans.modules.vmd.midp.propertyeditors.api.usercode.PropertyEditorUserCode;
068: import org.openide.awt.Mnemonics;
069: import org.openide.util.NbBundle;
070:
071: /**
072: *
073: * @author Karol Harezlak
074: * @author Anton Chechel
075: */
076: public final class PropertyEditorLayout extends PropertyEditorUserCode
077: implements PropertyEditorElement {
078:
079: private CustomEditorConstraints customEditor;
080: private JRadioButton radioButton;
081: private TypeID parentTypeID;
082:
083: private PropertyEditorLayout(TypeID parentTypeID) {
084: super (NbBundle.getMessage(PropertyEditorLayout.class,
085: "LBL_LAYOUT_STR_UCLABEL")); // NOI18N
086: this .parentTypeID = parentTypeID;
087: initComponents();
088:
089: initElements(Collections
090: .<PropertyEditorElement> singleton(this ));
091: }
092:
093: public static final PropertyEditorLayout createInstance() {
094: return new PropertyEditorLayout(null);
095: }
096:
097: public static final PropertyEditorLayout createInstance(
098: TypeID parentTypeID) {
099: return new PropertyEditorLayout(parentTypeID);
100: }
101:
102: private void initComponents() {
103: radioButton = new JRadioButton();
104: Mnemonics.setLocalizedText(radioButton, NbBundle.getMessage(
105: PropertyEditorLayout.class, "LBL_LAYOUT_STR")); // NOI18N
106: customEditor = new CustomEditorConstraints(0);
107: }
108:
109: public JComponent getCustomEditorComponent() {
110: return customEditor;
111: }
112:
113: public JRadioButton getRadioButton() {
114: return radioButton;
115: }
116:
117: public boolean isInitiallySelected() {
118: return true;
119: }
120:
121: public boolean isVerticallyResizable() {
122: return true;
123: }
124:
125: @Override
126: public String getAsText() {
127: String super Text = super .getAsText();
128: if (super Text != null) {
129: return super Text;
130: }
131: customEditor.setConstant(MidpTypes
132: .getInteger((PropertyValue) super .getValue()));
133: return customEditor.getBitmaskAsText();
134: }
135:
136: public void setTextForPropertyValue(String text) {
137: }
138:
139: public String getTextForPropertyValue() {
140: return null;
141: }
142:
143: public void updateState(PropertyValue value) {
144: if (isCurrentValueANull() || value == null) {
145: customEditor.setValue(0);
146: } else {
147: customEditor.setValue(MidpTypes.getInteger(value));
148: }
149: radioButton.setSelected(!isCurrentValueAUserCodeType());
150: }
151:
152: private void saveValue() {
153: super .setValue(MidpTypes.createIntegerValue(customEditor
154: .getBitMask()));
155: }
156:
157: @Override
158: public void customEditorOKButtonPressed() {
159: super .customEditorOKButtonPressed();
160: if (radioButton.isSelected()) {
161: saveValue();
162: }
163: }
164:
165: @Override
166: public Boolean canEditAsText() {
167: return false;
168: }
169:
170: @Override
171: public boolean canWrite() {
172: if (!isWriteableByParentType()) {
173: return false;
174: }
175:
176: return super .canWrite();
177: }
178:
179: @Override
180: public boolean supportsCustomEditor() {
181: if (!isWriteableByParentType()) {
182: return false;
183: }
184:
185: return super .supportsCustomEditor();
186: }
187:
188: private boolean isWriteableByParentType() {
189: if (component == null || component.get() == null) {
190: return false;
191: }
192:
193: if (parentTypeID != null) {
194: final DesignComponent _component = component.get();
195: final DesignComponent[] parent = new DesignComponent[1];
196: _component.getDocument().getTransactionManager()
197: .readAccess(new Runnable() {
198:
199: public void run() {
200: parent[0] = _component.getParentComponent();
201: }
202: });
203:
204: if (parent[0] != null
205: && parentTypeID.equals(parent[0].getType())) {
206: return false;
207: }
208: }
209: return true;
210: }
211:
212: private final class CustomEditorConstraints extends JPanel
213: implements ItemListener {
214:
215: private ItemLayouts layouts;
216: private Map<JToggleButton, BitmaskItem> bits;
217: private JPanel generalPanel;
218: private JPanel horizontalAlignmentPanel;
219: private JPanel verticalAlignmentPanel;
220: private JPanel newlinePanel;
221: private JPanel shrinkPanel;
222: private JPanel expandPanel;
223: private JCheckBox defaultCheckBox;
224: private JRadioButton horizontalAlignmentNoneCheckBox;
225: private JRadioButton verticalAlignmentNoneCheckBox;
226:
227: private int bitMask;
228:
229: CustomEditorConstraints(int bitmask) {
230:
231: this .bitMask = bitmask;
232: layouts = new ItemLayouts(bitmask);
233: bits = new HashMap<JToggleButton, BitmaskItem>();
234:
235: initComponents();
236: setLayoutDefault(defaultCheckBox.isSelected());
237: }
238:
239: void initComponents() {
240:
241: JToggleButton guiItem;
242: JRadioButton centerButton;
243: ButtonGroup buttonGroup;
244:
245: List<JToggleButton> guiItems = new ArrayList<JToggleButton>();
246:
247: setLayout(new GridLayout(6, 1));
248: generalPanel = new JPanel();
249: generalPanel.setLayout(new GridLayout(1, 2));
250: generalPanel.setBorder(BorderFactory
251: .createTitledBorder(Bundle
252: .getMessage("PNL_ITEMLAYOUTPE_GENERAL"))); // NOI18N
253:
254: defaultCheckBox = new JCheckBox(Bundle
255: .getMessage("LBL_ITEMLAYOUTPE_GEN_DEFAULT")); // NOI18N
256: defaultCheckBox.setMnemonic(Bundle
257: .getChar("MNM_ITEMLAYOUTPE_GEN_DEFAULT")); // NOI18N
258: integrateGuiItem(defaultCheckBox, layouts
259: .getBitmaskItem(ItemCD.VALUE_LAYOUT_DEFAULT));
260: defaultCheckBox.setSelected(layouts.getBitmask() == 0);
261: guiItems.add(defaultCheckBox);
262: generalPanel.add(defaultCheckBox);
263:
264: guiItem = new JCheckBox(Bundle
265: .getMessage("LBL_ITEMLAYOUTPE_GEN_MIDP2")); // NOI18N
266: guiItem.setMnemonic(Bundle
267: .getChar("MNM_ITEMLAYOUTPE_GEN_MIDP2")); // NOI18N
268: integrateGuiItem(guiItem, layouts
269: .getBitmaskItem(ItemCD.VALUE_LAYOUT_2));
270: guiItems.add(guiItem);
271: generalPanel.add(guiItem);
272:
273: this .add(generalPanel);
274:
275: horizontalAlignmentPanel = new JPanel();
276: horizontalAlignmentPanel.setLayout(new GridLayout(1, 4));
277: horizontalAlignmentPanel
278: .setBorder(BorderFactory.createTitledBorder(Bundle
279: .getMessage("PNL_ITEMLAYOUTPE_HORIZONTAL"))); // NOI18N
280: buttonGroup = new ButtonGroup();
281:
282: horizontalAlignmentNoneCheckBox = new JRadioButton(Bundle
283: .getMessage("LBL_ITEMLAYOUTPE_HOR_NONE")); // NOI18N
284: horizontalAlignmentNoneCheckBox.setMnemonic(Bundle
285: .getChar("MNM_ITEMLAYOUTPE_HOR_NONE")); // NOI18N
286: buttonGroup.add(horizontalAlignmentNoneCheckBox);
287: horizontalAlignmentPanel
288: .add(horizontalAlignmentNoneCheckBox);
289: horizontalAlignmentNoneCheckBox.setSelected(true);
290:
291: guiItem = new JRadioButton(Bundle
292: .getMessage("LBL_ITEMLAYOUTPE_HOR_LEFT")); // NOI18N
293: guiItem.setMnemonic(Bundle
294: .getChar("MNM_ITEMLAYOUTPE_HOR_LEFT")); // NOI18N
295: buttonGroup.add(guiItem);
296: integrateGuiItem(guiItem, layouts
297: .getBitmaskItem(ItemCD.VALUE_LAYOUT_LEFT));
298: guiItems.add(guiItem);
299: horizontalAlignmentPanel.add(guiItem);
300:
301: centerButton = new JRadioButton(Bundle
302: .getMessage("LBL_ITEMLAYOUTPE_HOR_CENTER")); // NOI18N
303: centerButton.setMnemonic(Bundle
304: .getChar("MNM_ITEMLAYOUTPE_HOR_CENTER")); // NOI18N
305: buttonGroup.add(centerButton);
306: guiItems.add(centerButton);
307: horizontalAlignmentPanel.add(centerButton);
308:
309: guiItem = new JRadioButton(Bundle
310: .getMessage("LBL_ITEMLAYOUTPE_HOR_RIGHT")); // NOI18N
311: guiItem.setMnemonic(Bundle
312: .getChar("MNM_ITEMLAYOUTPE_HOR_RIGHT")); // NOI18N
313: buttonGroup.add(guiItem);
314: integrateGuiItem(guiItem, layouts
315: .getBitmaskItem(ItemCD.VALUE_LAYOUT_RIGHT));
316: guiItems.add(guiItem);
317: horizontalAlignmentPanel.add(guiItem);
318:
319: integrateGuiItem(centerButton, layouts
320: .getBitmaskItem(ItemCD.VALUE_LAYOUT_CENTER));
321:
322: this .add(horizontalAlignmentPanel);
323:
324: // vertical alignment
325: verticalAlignmentPanel = new JPanel();
326: verticalAlignmentPanel.setLayout(new GridLayout(1, 4));
327: verticalAlignmentPanel.setBorder(BorderFactory
328: .createTitledBorder(Bundle
329: .getMessage("PNL_ITEMLAYOUTPE_VERTICAL"))); // NOI18N
330: buttonGroup = new ButtonGroup();
331:
332: verticalAlignmentNoneCheckBox = new JRadioButton(Bundle
333: .getMessage("LBL_ITEMLAYOUTPE_VER_NONE")); // NOI18N
334: verticalAlignmentNoneCheckBox.setMnemonic(Bundle
335: .getChar("MNM_ITEMLAYOUTPE_VER_NONE")); // NOI18N
336: verticalAlignmentNoneCheckBox.setSelected(true);
337: buttonGroup.add(verticalAlignmentNoneCheckBox);
338: verticalAlignmentPanel.add(verticalAlignmentNoneCheckBox);
339:
340: guiItem = new JRadioButton(Bundle
341: .getMessage("LBL_ITEMLAYOUTPE_VER_TOP")); // NOI18N
342: guiItem.setMnemonic(Bundle
343: .getChar("MNM_ITEMLAYOUTPE_VER_TOP")); // NOI18N
344: buttonGroup.add(guiItem);
345: integrateGuiItem(guiItem, layouts
346: .getBitmaskItem(ItemCD.VALUE_LAYOUT_TOP));
347: guiItems.add(guiItem);
348: verticalAlignmentPanel.add(guiItem);
349:
350: centerButton = new JRadioButton(Bundle
351: .getMessage("LBL_ITEMLAYOUTPE_VER_CENTER")); // NOI18N
352: centerButton.setMnemonic(Bundle
353: .getChar("MNM_ITEMLAYOUTPE_VER_CENTER")); // NOI18N
354: buttonGroup.add(centerButton);
355: guiItems.add(centerButton);
356: verticalAlignmentPanel.add(centerButton);
357:
358: guiItem = new JRadioButton(Bundle
359: .getMessage("LBL_ITEMLAYOUTPE_VER_BOTTOM")); // NOI18N
360: guiItem.setMnemonic(Bundle
361: .getChar("MNM_ITEMLAYOUTPE_VER_BOTTOM")); // NOI18N
362: buttonGroup.add(guiItem);
363: integrateGuiItem(guiItem, layouts
364: .getBitmaskItem(ItemCD.VALUE_LAYOUT_BOTTOM));
365: guiItems.add(guiItem);
366: verticalAlignmentPanel.add(guiItem);
367:
368: integrateGuiItem(centerButton, layouts
369: .getBitmaskItem(ItemCD.VALUE_LAYOUT_VCENTER));
370:
371: this .add(verticalAlignmentPanel);
372:
373: newlinePanel = new JPanel();
374: newlinePanel.setLayout(new GridLayout(1, 2));
375: newlinePanel.setBorder(BorderFactory
376: .createTitledBorder(Bundle
377: .getMessage("PNL_ITEMLAYOUTPE_NEWLINE"))); // NOI18N
378: guiItem = new JCheckBox(Bundle
379: .getMessage("LBL_ITEMLAYOUTPE_NL_BEFORE")); // NOI18N
380: guiItem.setMnemonic(Bundle
381: .getChar("MNM_ITEMLAYOUTPE_NL_BEFORE")); // NOI18N
382: integrateGuiItem(guiItem, layouts
383: .getBitmaskItem(ItemCD.VALUE_LAYOUT_NEWLINE_BEFORE));
384: guiItems.add(guiItem);
385: newlinePanel.add(guiItem);
386:
387: guiItem = new JCheckBox(Bundle
388: .getMessage("LBL_ITEMLAYOUTPE_NL_AFTER")); // NOI18N
389: guiItem.setMnemonic(Bundle
390: .getChar("MNM_ITEMLAYOUTPE_NL_AFTER")); // NOI18N
391: integrateGuiItem(guiItem, layouts
392: .getBitmaskItem(ItemCD.VALUE_LAYOUT_NEWLINE_AFTER));
393: guiItems.add(guiItem);
394: newlinePanel.add(guiItem);
395:
396: this .add(newlinePanel);
397:
398: // Shrink
399: shrinkPanel = new JPanel();
400: shrinkPanel.setLayout(new GridLayout(1, 2));
401: shrinkPanel.setBorder(BorderFactory
402: .createTitledBorder(Bundle
403: .getMessage("PNL_ITEMLAYOUTPE_SHRINK"))); // NOI18N
404: guiItem = new JCheckBox(Bundle
405: .getMessage("LBL_ITEMLAYOUTPE_SH_HORIZONTAL")); // NOI18N
406: guiItem.setMnemonic(Bundle
407: .getChar("MNM_ITEMLAYOUTPE_SH_HORIZONTAL")); // NOI18N
408: integrateGuiItem(guiItem, layouts
409: .getBitmaskItem(ItemCD.VALUE_LAYOUT_SHRINK));
410: guiItems.add(guiItem);
411: shrinkPanel.add(guiItem);
412:
413: guiItem = new JCheckBox(Bundle
414: .getMessage("LBL_ITEMLAYOUTPE_SH_VERTICAL")); // NOI18N
415: guiItem.setMnemonic(Bundle
416: .getChar("MNM_ITEMLAYOUTPE_SH_VERTICAL")); // NOI18N
417: integrateGuiItem(guiItem, layouts
418: .getBitmaskItem(ItemCD.VALUE_LAYOUT_VSHRINK));
419: guiItems.add(guiItem);
420: shrinkPanel.add(guiItem);
421:
422: this .add(shrinkPanel);
423:
424: // Expand
425: expandPanel = new JPanel();
426: expandPanel.setLayout(new GridLayout(1, 2));
427: expandPanel.setBorder(BorderFactory
428: .createTitledBorder(Bundle
429: .getMessage("PNL_ITEMLAYOUTPE_EXPAND"))); // NOI18N
430: guiItem = new JCheckBox(Bundle
431: .getMessage("LBL_ITEMLAYOUTPE_EX_HORIZONTAL")); // NOI18N
432: guiItem.setMnemonic(Bundle
433: .getChar("MNM_ITEMLAYOUTPE_EX_HORIZONTAL")); // NOI18N
434: integrateGuiItem(guiItem, layouts
435: .getBitmaskItem(ItemCD.VALUE_LAYOUT_EXPAND));
436: guiItems.add(guiItem);
437: expandPanel.add(guiItem);
438:
439: guiItem = new JCheckBox(Bundle
440: .getMessage("LBL_ITEMLAYOUTPE_EX_VERTICAL")); // NOI18N
441: guiItem.setMnemonic(Bundle
442: .getChar("MNM_ITEMLAYOUTPE_EX_VERTICAL")); // NOI18N
443: integrateGuiItem(guiItem, layouts
444: .getBitmaskItem(ItemCD.VALUE_LAYOUT_VEXPAND));
445: guiItems.add(guiItem);
446: expandPanel.add(guiItem);
447:
448: this .add(expandPanel);
449:
450: // now add listeners to all guiItems
451: for (JToggleButton button : guiItems) {
452: button.addItemListener(this );
453: }
454: }
455:
456: public void setConstant(int bitmask) {
457: layouts.setBitmask(bitmask);
458: this .bitMask = bitmask;
459: }
460:
461: public void itemStateChanged(ItemEvent e) {
462: Object source = e.getItemSelectable();
463:
464: if (source == defaultCheckBox) {
465: boolean selected = (e.getStateChange() == ItemEvent.SELECTED);
466: setLayoutDefault(selected);
467: int newBitmask = 0;
468: if (!selected)
469: newBitmask = getComponentsBitmask().getBitmask();
470: bitMask = newBitmask;
471: } else {
472: BitmaskItem bitmaskItem = bits.get(source);
473: assert (bitmaskItem != null);
474: boolean state = (e.getStateChange() == ItemEvent.SELECTED);
475: bitMask = layouts.addToBitmask(bitmaskItem, state);
476: }
477: }
478:
479: private void integrateGuiItem(JToggleButton guiItem,
480: BitmaskItem bitmaskItem) {
481: guiItem.setSelected(layouts.isSet(bitmaskItem));
482: bits.put(guiItem, bitmaskItem);
483: }
484:
485: private void setLayoutDefault(boolean layoutDefault) {
486: // need to disable all groups except default button
487: boolean nonDefault = !layoutDefault;
488:
489: for (JToggleButton button : bits.keySet()) {
490: button.setEnabled(nonDefault);
491: }
492: defaultCheckBox.setEnabled(true);
493: // don't forget at horizontal/vertical none settings
494: horizontalAlignmentNoneCheckBox.setEnabled(nonDefault);
495: verticalAlignmentNoneCheckBox.setEnabled(nonDefault);
496: }
497:
498: private ItemLayouts getComponentsBitmask() {
499: ItemLayouts _layouts = new ItemLayouts(0);
500: for (JToggleButton button : bits.keySet()) {
501: if (button.isSelected()) {
502: _layouts.addToBitmask(bits.get(button), true);
503: }
504: }
505:
506: return _layouts;
507: }
508:
509: public void setValue(int value) {
510: if (value == 0) {
511: defaultCheckBox.setSelected(true);
512: itemStateChanged(new ItemEvent(defaultCheckBox,
513: ItemEvent.ITEM_STATE_CHANGED, null,
514: ItemEvent.SELECTED));
515: } else {
516: setConstant(value);
517: }
518: }
519:
520: public int getBitMask() {
521: return bitMask;
522: }
523:
524: public String getBitmaskAsText() {
525: if (layouts.getBitmask() == ItemCD.VALUE_LAYOUT_DEFAULT) {
526: return layouts.getBitmaskItem(layouts.getBitmask())
527: .getName();
528: } else if (layouts.getBitmask() == ItemCD.VALUE_LAYOUT_2) {
529: return layouts.getBitmaskItem(layouts.getBitmask())
530: .getName();
531: }
532:
533: int bitmaskRadioButton1 = 0;
534: int bitmaskRadioButton2 = 0;
535: StringBuffer bitmaskAsTextCheckBoxes = new StringBuffer();
536: StringBuffer bitmaskAsTextRadioButton1 = new StringBuffer();
537: StringBuffer bitmaskAsTextRadioButton2 = new StringBuffer();
538: StringBuffer separator = new StringBuffer(" | "); // NOI18N
539:
540: for (JToggleButton button : bits.keySet()) {
541: if (layouts.isSet(bits.get(button))
542: && button instanceof JRadioButton
543: && bits.get(button).getAffectedBits() < 16
544: && bitmaskRadioButton1 < bits.get(button)
545: .getAffectedBits()) {
546: bitmaskRadioButton1 = bits.get(button)
547: .getAffectedBits();
548: bitmaskAsTextRadioButton1 = new StringBuffer(bits
549: .get(button).getName());
550: bitmaskAsTextRadioButton1.append(separator);
551: } else if (layouts.isSet(bits.get(button))
552: && button instanceof JRadioButton
553: && bits.get(button).getAffectedBits() >= 16
554: && bitmaskRadioButton2 < bits.get(button)
555: .getAffectedBits()) {
556: bitmaskRadioButton2 = bits.get(button)
557: .getAffectedBits();
558: bitmaskAsTextRadioButton2 = new StringBuffer(bits
559: .get(button).getName());
560: bitmaskAsTextRadioButton2.append(separator);
561:
562: } else if (layouts.isSet(bits.get(button))
563: && button instanceof JCheckBox
564: && bits.get(button).getAffectedBits() != ItemCD.VALUE_LAYOUT_DEFAULT) {
565: bitmaskAsTextCheckBoxes.append(bits.get(button)
566: .getName());
567: bitmaskAsTextCheckBoxes.append(separator);
568: }
569: }
570:
571: bitmaskAsTextRadioButton1.append(bitmaskAsTextRadioButton2
572: .append(bitmaskAsTextCheckBoxes));
573: bitmaskAsTextRadioButton1
574: .deleteCharAt(bitmaskAsTextRadioButton1
575: .lastIndexOf(separator.toString().trim()));
576:
577: return bitmaskAsTextRadioButton1.toString();
578: }
579: }
580: }
|