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.xml.schema.abe;
043:
044: import java.awt.Color;
045: import java.awt.Cursor;
046: import java.awt.Dimension;
047: import java.awt.FlowLayout;
048: import java.awt.dnd.DropTargetDragEvent;
049: import java.awt.dnd.DropTargetDropEvent;
050: import java.awt.dnd.DropTargetEvent;
051: import java.awt.event.ActionEvent;
052: import java.awt.event.ActionListener;
053: import java.awt.event.KeyEvent;
054: import java.awt.event.KeyListener;
055: import java.awt.event.MouseAdapter;
056: import java.awt.event.MouseEvent;
057: import java.beans.PropertyChangeEvent;
058: import java.beans.PropertyChangeListener;
059: import javax.swing.JLabel;
060: import javax.swing.JTextField;
061: import javax.swing.border.Border;
062: import javax.swing.border.EmptyBorder;
063: import javax.swing.border.LineBorder;
064: import org.netbeans.modules.xml.axi.AXIComponent;
065: import org.netbeans.modules.xml.axi.AXIContainer;
066: import org.netbeans.modules.xml.axi.AXIModel;
067: import org.netbeans.modules.xml.axi.AbstractAttribute;
068: import org.netbeans.modules.xml.axi.AnyAttribute;
069: import org.netbeans.modules.xml.axi.Attribute;
070: import org.netbeans.modules.xml.axi.ContentModel;
071: import org.netbeans.modules.xml.schema.abe.nodes.ABEAbstractNode;
072: import org.netbeans.modules.xml.schema.abe.nodes.AttributeNode;
073: import org.netbeans.modules.xml.schema.abe.palette.DnDHelper;
074: import org.openide.util.NbBundle;
075:
076: /*import org.netbeans.modules.xml.schema.ui.nodes.categorized.customizer.AdvancedLocalAttributeCustomizer;
077: import org.openide.DialogDescriptor;
078: import org.openide.DialogDisplayer;*/
079:
080: /**
081: *
082: *
083: * @author Todd Fast, todd.fast@sun.com
084: */
085: public class AttributePanel extends ABEBaseDropPanel {
086: private static final long serialVersionUID = 7526472295622776147L;
087: private static final Border normalBorder = new EmptyBorder(2, 2, 2,
088: 2);//LineBorder(Color.WHITE/*InstanceDesignConstants.TAG_OUTLINE_COLOR*/, 1);
089: private static final Border selectedBorder = new LineBorder(
090: InstanceDesignConstants.XP_ORANGE, 2);
091:
092: /**
093: * Default constructor
094: *
095: */
096: public AttributePanel(StartTagPanel elementPanel,
097: AbstractAttribute attribute, final InstanceUIContext context) {
098: super (context);
099: this .startTagPanel = elementPanel;
100: this .attribute = attribute;
101: initialize();
102: attribute.addPropertyChangeListener(new ModelEventMediator(
103: this , attribute) {
104: public void _propertyChange(PropertyChangeEvent evt) {
105: String str = evt.getPropertyName();
106: if (str.equals(Attribute.PROP_NAME)
107: || str.equals(Attribute.PROP_TYPE))
108: attributePropertyChangeAction(evt);
109: }
110: });
111: initKeyListener();
112: addSelectionListener();
113: makeNBNode();
114: //installFocusManager();
115: }
116:
117: protected void initMouseListener() {
118: addMouseListener(new MouseAdapter() {
119: public void mouseReleased(MouseEvent e) {
120: mouseClickedActionHandler(e, true);
121: }
122:
123: public void mousePressed(MouseEvent e) {
124: mouseClickedActionHandler(e, true);
125: }
126:
127: public void mouseClicked(MouseEvent e) {
128: mouseClickedActionHandler(e, false);
129: }
130:
131: });
132: }
133:
134: /**
135: *
136: *
137: */
138: Color attrColor = InstanceDesignConstants.ATTRIBUTE_COLOR;
139: Color attrBGColor = InstanceDesignConstants.NO_BACKGROUND_COLOR;
140:
141: private void initialize() {
142: setLayout(new FlowLayout(FlowLayout.CENTER, 1, HEAD_ROOM_SPACE));
143: AbstractAttribute attr = getAttribute();
144: boolean shared = attr.isShared();/*attr.getContentModel() == null ? false :
145: ((attr.getContentModel().getType() == ContentModel.ContentModelType.ATTRIBUTE_GROUP) ?
146: true : false);*/
147: boolean readOnly = attr.isReadOnly();
148: String valueTTP = NbBundle.getMessage(AttributePanel.class,
149: "TTP_ATTR_LABEL_VALUE");
150: String nameTTP = NbBundle.getMessage(AttributePanel.class,
151: "TTP_ATTR_LABEL_NAME");
152: String attrTTP = NbBundle.getMessage(AttributePanel.class,
153: "TTP_ATTR");
154: setOpaque(false);
155: setBorder(normalBorder);
156: if (shared || attr.isGlobal()) {
157: attrBGColor = InstanceDesignConstants.ATTR_BG_SHARED_COLOR;
158: setBackground(attrBGColor);
159: setOpaque(true);
160: attrColor = InstanceDesignConstants.ATTRIBUTE_COLOR;
161: if (attr.isGlobal()) {
162: valueTTP = NbBundle.getMessage(AttributePanel.class,
163: "TTP_ATTR_LABEL_VALUE_GLOBAL");
164: nameTTP = NbBundle.getMessage(AttributePanel.class,
165: "TTP_ATTR_LABEL_NAME_GLOBAL");
166: attrTTP = NbBundle.getMessage(AttributePanel.class,
167: "TTP_ATTR_GLOBAL");
168: } else {
169: if (attr.getContentModel() != null) {
170: String name = attr.getContentModel().getName();
171: String typeStr = attr
172: .getContentModel()
173: .getType()
174: .equals(
175: ContentModel.ContentModelType.ATTRIBUTE_GROUP) ? "LBL_GLOBAL_ATTRIBUTE_GROUP"
176: : "LBL_GLOBAL_COMPLEX_TYPE";
177:
178: typeStr = NbBundle.getMessage(AttributePanel.class,
179: typeStr);
180:
181: valueTTP = NbBundle.getMessage(
182: AttributePanel.class,
183: "TTP_ATTR_LABEL_VALUE_SHARED", typeStr,
184: name);
185: nameTTP = NbBundle
186: .getMessage(AttributePanel.class,
187: "TTP_ATTR_LABEL_NAME_SHARED",
188: typeStr, name);
189: attrTTP = NbBundle.getMessage(AttributePanel.class,
190: "TTP_ATTR_SHARED", typeStr, name);
191: } else {
192: String elmName = attr.getParentElement().getName();
193: valueTTP = NbBundle.getMessage(
194: AttributePanel.class,
195: "TTP_ATTR_LABEL_VALUE_SHARED_NO_CM",
196: elmName);
197: nameTTP = NbBundle
198: .getMessage(AttributePanel.class,
199: "TTP_ATTR_LABEL_NAME_SHARED_NO_CM",
200: elmName);
201: attrTTP = NbBundle.getMessage(AttributePanel.class,
202: "TTP_ATTR_SHARED_NO_CM", elmName);
203: }
204: }
205: }
206: if (readOnly) {
207: attrBGColor = InstanceDesignConstants.ATTR_BG_READONLY_COLOR;
208: setBackground(attrBGColor);
209: setOpaque(true);
210: attrColor = InstanceDesignConstants.TAG_NAME_READONLY_COLOR;
211: valueTTP = NbBundle.getMessage(AttributePanel.class,
212: "TTP_ATTR_LABEL_VALUE_READONLY");
213: nameTTP = NbBundle.getMessage(AttributePanel.class,
214: "TTP_ATTR_LABEL_NAME_READONLY");
215: attrTTP = NbBundle.getMessage(AttributePanel.class,
216: "TTP_ATTR_READONLY");
217: }
218:
219: setToolTipText(attrTTP);
220:
221: attributeNameLabel = new InplaceEditableLabel(attr.getName());
222: attributeNameLabel.setForeground(attrColor);
223: attributeNameLabel.setToolTipText(nameTTP);
224: add(attributeNameLabel);
225:
226: equals = new JLabel(" = ");
227: equals.setForeground(attrColor);
228: equals.setToolTipText(attrTTP);
229: add(equals);
230: //transmit mouse click events on eq sign to the attr panel
231: equals.addMouseListener(new MouseAdapter() {
232: public void mouseReleased(MouseEvent e) {
233: AttributePanel.this .dispatchEvent(e);
234: }
235:
236: public void mousePressed(MouseEvent e) {
237: AttributePanel.this .dispatchEvent(e);
238: }
239:
240: public void mouseClicked(MouseEvent e) {
241: AttributePanel.this .dispatchEvent(e);
242: }
243:
244: });
245:
246: String value = "?";
247: if (attr instanceof Attribute) {
248: Attribute a = (Attribute) attr;
249: if (a.getType() != null)
250: value = a.getType().getName();
251: }
252:
253: attributeValueLabel = new InplaceEditableLabel(value);
254: attributeValueLabel.setForeground(attrColor);
255: attributeValueLabel.setToolTipText(valueTTP);
256: add(attributeValueLabel);
257:
258: refreshAttributeParameters();
259: initAttributeEditListeners();
260: initMouseListener();
261: }
262:
263: protected void initKeyListener() {
264: addKeyListener(new KeyListener() {
265: public void keyPressed(KeyEvent e) {
266: //name edit
267: if (e.getKeyCode() == e.VK_F2) {
268: attributeNameLabel.showEditor();
269: }
270: if (context.getFocusTraversalManager()
271: .isFocusChangeEvent(e))
272: context.getFocusTraversalManager().handleEvent(e,
273: AttributePanel.this );
274: }
275:
276: public void keyReleased(KeyEvent e) {
277: }
278:
279: public void keyTyped(KeyEvent e) {
280: if (e.getKeyChar() == e.VK_SPACE) {
281: attributeNameLabel.showEditor();
282: }
283: }
284: });
285: }
286:
287: protected void mouseClickedActionHandler(MouseEvent e,
288: boolean handelPopupOnly) {
289: if (e.getClickCount() == 1) {
290: if (e.isPopupTrigger()) {
291: context.getMultiComponentActionManager().showPopupMenu(
292: e, this );
293: return;
294: }
295: if (handelPopupOnly)
296: return;
297: //the attr is selected
298: if (e.isControlDown())
299: context.getComponentSelectionManager()
300: .addToSelectedComponents(this );
301: else
302: context.getComponentSelectionManager()
303: .setSelectedComponent(this );
304: }
305: }
306:
307: /**
308: *
309: *
310: */
311: public AbstractAttribute getAttribute() {
312: return attribute;
313: }
314:
315: public void refreshAttributeParameters() {
316: attributeNameLabel.setText(getAttribute().toString());
317: String value = "?";
318: AbstractAttribute attr = getAttribute();
319: if (attr instanceof Attribute) {
320: Attribute a = (Attribute) attr;
321: if (a.getType() != null)
322: value = a.getType().getName();
323: }
324:
325: attributeValueLabel.setText(value);
326: }
327:
328: public Dimension getPreferredSize() {
329: return new Dimension(super .getPreferredSize().width,
330: getAttributePanelHeight());
331: }
332:
333: private void initAttributeEditListeners() {
334: initAttributeNameEditListener();
335: initAttributeValueEditListener();
336: }
337:
338: protected void initAttributeNameEditListener() {
339:
340: attributeNameLabel
341: .addCtrlClickHandler(new InplaceEditableLabel.CtrlClickHandler() {
342: public void handleCtrlClick() {
343: getNBNode().showSuperDefinition();
344: }
345: });
346:
347: attributeNameLabel.setInputValidator(new InputValidator() {
348: public boolean isStringValid(String input) {
349: return org.netbeans.modules.xml.xam.dom.Utils
350: .isValidNCName(input);
351: }
352: }, NbBundle
353: .getMessage(AttributePanel.class, "MSG_NOT_A_NCNAME"));
354: attributeNameLabel
355: .addPropertyChangeListener(new PropertyChangeListener() {
356: public void propertyChange(PropertyChangeEvent evt) {
357: if (evt
358: .getPropertyName()
359: .equals(
360: InplaceEditableLabel.PROPERTY_MODE_CHANGE)) {
361: if (evt.getNewValue() == InplaceEditableLabel.Mode.EDIT) {
362: //user selected edit give the editor JComponent
363: //show a text field
364: final JTextField field = new JTextField(
365: getAttribute().toString());
366: field.select(0, field.getText()
367: .length());
368: field
369: .addActionListener(new ActionListener() {
370: public void actionPerformed(
371: ActionEvent e) {
372: String newName = field
373: .getText();
374: //do validation
375: if (org.netbeans.modules.xml.xam.dom.Utils
376: .isValidNCName(newName)) {
377: field
378: .setCursor(new Cursor(
379: Cursor.WAIT_CURSOR));
380: try {
381: if (firstTimeRename)
382: getNBNode()
383: .setNameInModel(
384: newName);
385: else
386: setAttrNameInModel(newName);
387: firstTimeRename = false;
388: } finally {
389: field
390: .setCursor(new Cursor(
391: Cursor.DEFAULT_CURSOR));
392: }
393: }
394: }
395: });
396:
397: if (attribute.isShared()
398: || attribute.isGlobal()) {
399: String str = NbBundle
400: .getMessage(
401: StartTagPanel.class,
402: "MSG_SHARED_ATTRIBUTE_EDIT");
403: attributeNameLabel.setEditInfoText(
404: str, context);
405: }
406: if (!attribute.isReadOnly()) {
407: if (attribute instanceof AnyAttribute) {
408: String str = NbBundle
409: .getMessage(
410: StartTagPanel.class,
411: "MSG_ANY_ATTRIBUTE_EDIT");
412: attributeNameLabel
413: .setEditInfoText(str,
414: context);
415: } else {
416: //attributeNameLabel.setWidthMagnificationFactor(1);
417: attributeNameLabel
418: .setInlineEditorComponent(field);
419: }
420: } else {
421: String str = NbBundle
422: .getMessage(
423: StartTagPanel.class,
424: "MSG_READONLY_ATTRIBUTE_EDIT");
425: attributeNameLabel.setEditInfoText(
426: str, context);
427: }
428: }
429: }
430: }
431: });
432: }
433:
434: protected void initAttributeValueEditListener() {
435: attributeValueLabel
436: .addPropertyChangeListener(new PropertyChangeListener() {
437: public void propertyChange(PropertyChangeEvent evt) {
438: if (evt
439: .getPropertyName()
440: .equals(
441: InplaceEditableLabel.PROPERTY_MODE_CHANGE)) {
442: if (evt.getNewValue() == InplaceEditableLabel.Mode.EDIT) {
443: attributeValueLabel.hideEditor();
444: }
445: }
446: }
447: });
448: }
449:
450: private void setAttrNameInModel(String name) {
451: getNBNode().setName(name);
452: }
453:
454: private void setAttrValueInModel(String name) {
455: //TODO
456: }
457:
458: public void removeAttribute() {
459: AXIContainer elm = startTagPanel.getElementPanel()
460: .getAXIContainer();
461: AXIModel model = elm.getModel();
462: if (model != null) {
463: model.startTransaction();
464: try {
465: elm.removeAttribute(attribute);
466: } finally {
467: model.endTransaction();
468: }
469: }
470: }
471:
472: private void attributePropertyChangeAction(PropertyChangeEvent evt) {
473: refreshAttributeParameters();
474: }
475:
476: private void addAttributeToAttrGrp() {
477: /*if(getAttribute().getContentModel().getType() ==
478: ContentModel.ContentModelType.ATTRIBUTE_GROUP){*/
479: ContentModel cm = getAttribute().getContentModel();
480: AXIModel model = context.getAXIModel();
481: model.startTransaction();
482: try {
483: Attribute attr = model.getComponentFactory()
484: .createAttribute();
485: String str = UIUtilities.getUniqueName(
486: InstanceDesignConstants.NEW_ATTRIBUTE_NAME, cm);
487: attr.setName(str);
488: cm.addAttribute(attr);
489: } finally {
490: model.endTransaction();
491: }
492: //}
493: }
494:
495: public void drop(DropTargetDropEvent event) {
496: removeDragFeedback();
497: ContentModel cm = getAttribute().getContentModel();
498: if ((cm != null)
499: && (cm.getType() == ContentModel.ContentModelType.ATTRIBUTE_GROUP)) {
500: addAttributeToAttrGrp();
501: } else {
502: event.rejectDrop();
503: }
504: }
505:
506: public void dragOver(DropTargetDragEvent event) {
507: DnDHelper.PaletteItem item = DnDHelper
508: .getDraggedPaletteItem(event);
509: if (item != DnDHelper.PaletteItem.ATTRIBUTE) {
510: event.rejectDrag();
511: return;
512: }
513: ContentModel cm = getAttribute().getContentModel();
514: if ((cm != null)
515: && (cm.getType() == ContentModel.ContentModelType.ATTRIBUTE_GROUP)) {
516: return;
517: }
518: event.rejectDrag();
519: }
520:
521: public void dragEnter(DropTargetDragEvent event) {
522: DnDHelper.PaletteItem item = DnDHelper
523: .getDraggedPaletteItem(event);
524: if (item != DnDHelper.PaletteItem.ATTRIBUTE) {
525: String str = NbBundle.getMessage(AttributePanel.class,
526: "MSG_ATTRIBUTE_PANEL_DROP_REJECT_WRONG_COMPONENT",
527: this .attribute.getName());
528: UIUtilities.showErrorMessageFor(str, context, this );
529: event.rejectDrag();
530: }
531:
532: setDragFeedback();
533: ContentModel cm = getAttribute().getContentModel();
534: if ((cm != null)
535: && (cm.getType() == ContentModel.ContentModelType.ATTRIBUTE_GROUP)) {
536: String str = NbBundle.getMessage(AttributePanel.class,
537: "MSG_ATTRIBUTE_PANEL_DROP_ACCEPT", getAttribute()
538: .getContentModel().getName());
539: UIUtilities.showBulbMessageFor(str, context, this );
540: return;
541: }
542: String str = NbBundle.getMessage(AttributePanel.class,
543: "MSG_ATTRIBUTE_PANEL_DROP_REJECT", this .attribute
544: .getName());
545: UIUtilities.showErrorMessageFor(str, context, this );
546: event.rejectDrag();
547: }
548:
549: public void dragExit(DropTargetEvent event) {
550: removeDragFeedback();
551: }
552:
553: public void setDragFeedback() {
554: setBackground(InstanceDesignConstants.DARK_BLUE);
555: setOpaque(true);
556: attributeNameLabel.setForeground(Color.WHITE);
557: attributeValueLabel.setForeground(Color.WHITE);
558: equals.setForeground(Color.WHITE);
559: setBorder(new LineBorder(InstanceDesignConstants.DARK_BLUE, 2));
560: revalidate();
561: }
562:
563: public void removeDragFeedback() {
564: UIUtilities.hideGlassMessage();
565: if (attrBGColor == InstanceDesignConstants.NO_BACKGROUND_COLOR)
566: setOpaque(false);
567: else
568: setBackground(attrBGColor);
569: attributeNameLabel.setForeground(attrColor);
570: attributeValueLabel.setForeground(attrColor);
571: equals.setForeground(attrColor);
572: setBorder(normalBorder);
573: revalidate();
574: }
575:
576: void showEditorForName(boolean firstTimeRename) {
577: this .firstTimeRename = firstTimeRename;
578: attributeNameLabel.showEditor();
579: }
580:
581: public static int getAttributePanelHeight() {
582: return ATTR_HEIGHT;
583: }
584:
585: protected void makeNBNode() {
586: attributeNode = new AttributeNode(attribute, context);
587: if (attribute.isReadOnly())
588: attributeNode.setReadOnly(true);
589: }
590:
591: public ABEAbstractNode getNBNode() {
592: return attributeNode;
593: }
594:
595: public AXIComponent getAXIComponent() {
596: return attribute;
597: }
598:
599: private void addSelectionListener() {
600: addPropertyChangeListener(new PropertyChangeListener() {
601: public void propertyChange(PropertyChangeEvent evt) {
602: if (evt.getPropertyName().equals(PROP_SELECTED)) {
603: if (((Boolean) evt.getNewValue()).booleanValue()) {
604: /*Font font = attributeNameLabel.getFont();
605: font = new Font(font.getName(), Font.BOLD, font.getSize());
606: attributeNameLabel.setFont(font);
607: attributeValueLabel.setFont(font);
608: equals.setFont(font);*/
609:
610: attributeNameLabel.setForeground(Color.BLACK);
611: attributeValueLabel.setForeground(Color.BLACK);
612: equals.setForeground(Color.BLACK);
613: setBorder(selectedBorder);
614: revalidate();
615: } else {
616: attributeNameLabel.setForeground(attrColor);
617: attributeValueLabel.setForeground(attrColor);
618: equals.setForeground(attrColor);
619: setBorder(normalBorder);
620: revalidate();
621: }
622:
623: }
624: }
625: });
626: }
627:
628: public void accept(UIVisitor visitor) {
629: visitor.visit(this );
630: }
631:
632: ////////////////////////////////////////////////////////////////////////////
633: // Class members
634: ////////////////////////////////////////////////////////////////////////////
635:
636: private static final int ATTR_HEIGHT = TagPanel.getTagHeight() - 10;
637: private static final int INTER_LABEL_SPACE = 5;
638: public static final int HEAD_ROOM_SPACE = (getAttributePanelHeight() / 2) - 11;
639:
640: ////////////////////////////////////////////////////////////////////////////
641: // Instance members
642: ////////////////////////////////////////////////////////////////////////////
643:
644: private JLabel equals;
645: private StartTagPanel startTagPanel;
646: private AbstractAttribute attribute;
647: private InplaceEditableLabel attributeNameLabel;
648: private InplaceEditableLabel attributeValueLabel;
649: private AttributeNode attributeNode;
650:
651: }
|