// File: ConstEdgePanel.java // Classes: ConstEdgePanel // Author: Kedar Patankar package edu.neu.ccs.demeter.tools.apstudio.graphedit; import java.awt.Panel; import java.awt.TextField; import java.awt.Choice; import java.awt.Color; import java.awt.event.ActionListener; import java.awt.event.FocusListener; import java.awt.event.ActionEvent; import java.awt.event.FocusEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import edu.neu.ccs.demeter.tools.apstudio.ui.PropsGridLayout; /* Purpose : Property sheet for construction edges and repetition edges. This displays as well allows to modify the properties */ public class ConstEdgePanel extends Panel implements ActionListener, FocusListener, ItemListener { private Editor _editor; private PropertyWindow _pw; private String _edgeName,_before,_after,_cardinality,_from,_to,_panicName; private TextField _edgeNameText,_beforeText,_afterText,_fromText,_toText; private Choice _cardinalityChoice; private Choice _partModifierChoice; // not implemented private UConstEdge _edge; public ConstEdgePanel(Editor editor,PropertyWindow pw) // constructor { _editor = editor; _pw = pw; setLayout(new PropsGridLayout(5,5)); TextField edgeNameLabel,beforeLabel,afterLabel,cardinalityLabel,modifierLabel,fromLabel,toLabel; edgeNameLabel = new TextField("Edge Name"); beforeLabel = new TextField("Syntax:Before"); afterLabel= new TextField("Syntax:After"); cardinalityLabel = new TextField("Cardinality"); modifierLabel = new TextField("Edge Modifier"); fromLabel = new TextField("From"); toLabel = new TextField("To"); edgeNameLabel.setEditable(false); beforeLabel.setEditable(false); afterLabel.setEditable(false); cardinalityLabel.setEditable(false); modifierLabel.setEditable(false); fromLabel.setEditable(false); toLabel.setEditable(false); _edgeNameText = new TextField(); _beforeText = new TextField(); _afterText = new TextField(); _edgeNameText.addActionListener(this); _beforeText.addActionListener(this); _afterText.addActionListener(this); _edgeNameText.addFocusListener(this); _beforeText.addFocusListener(this); _afterText.addFocusListener(this); _cardinalityChoice = new Choice(); _cardinalityChoice.addItem("1"); _cardinalityChoice.addItem("0..1"); _cardinalityChoice.addItem("0..*"); _cardinalityChoice.addItem("1..*"); _cardinalityChoice.addItemListener(this); _partModifierChoice = new Choice(); _partModifierChoice.addItem("None"); _partModifierChoice.addItem("Final"); _partModifierChoice.addItem("Static"); _partModifierChoice.addItem("private"); _partModifierChoice.addItem("Read Only"); _partModifierChoice.setEnabled(false); _fromText = new TextField(); _toText = new TextField(); _fromText.setEditable(false); _toText.setEditable(false); add(edgeNameLabel); add(_edgeNameText); add(beforeLabel); add(_beforeText); add(afterLabel); add(_afterText); add(cardinalityLabel); add(_cardinalityChoice); add(modifierLabel); add(_partModifierChoice); add(fromLabel); add(_fromText); add(toLabel); add(_toText); setBackground(Color.lightGray); } // Display the values for the first time. This method shows construction edge public void setValues(UConstEdge e,String name,String cardinality,String before,String after,String from, String to) { _edgeName = name; _panicName = name; // This name is used as default when the cardinality is changed. // Repetition edges can't have names but user can switch between repetition and construction edge very // easily. _edge = e; if(name == null) { ArcPerspective a = _edge.get_persp(); String edgeName = a.get_DestinationName(); Perspective p = a.get_sourcePerspective(); UConstOrAltVertex u = (UConstOrAltVertex)p.owner(); edgeName = edgeName.toLowerCase(); if(u.checkThisOut(edgeName)) { int count =0; for(boolean found = true;found;) { count++; String trialName = edgeName + count; found = u.checkThisOut(trialName); } edgeName = edgeName +"_"+ count; } _panicName = edgeName; _edgeNameText.setText("Not Applicable"); _edgeNameText.setEditable(false); _edgeNameText.setEnabled(false); } else { _edgeNameText.setText(name); _edgeNameText.setEditable(true); _edgeNameText.setEnabled(true); } if(before == null) { _beforeText.setText(""); _before = null; } else { _beforeText.setText(before); _before = before; } if(after == null) { _afterText.setText(""); _after =null; } else { _afterText.setText(after); _after = after; } _fromText.setText(from); _toText.setText(to); int index=0; if ("1".equals(cardinality)) index = 0; else if ("0..1".equals(cardinality)) index = 1; else if ("0..*".equals(cardinality)) index = 2; else if ("1..*".equals(cardinality)) index = 3; _cardinalityChoice.select(index); _partModifierChoice.select(0); } // Event handling. Need to consider only ActionEvent and FocusEvent // All changes are made only when user presses enter key and the new value is appropriate. // If the focus is lost before hitting enter key old value is restored. public void actionPerformed(ActionEvent event) { Object source = event.getSource(); if(source == _edgeNameText) { String newName = _edgeNameText.getText().trim(); // Validating the new name if(newName.length()<=0) { _pw.showMessage("Name is compulsory"); return; } String oldName; if(_edgeName == null) oldName =""; else oldName = _edgeName; if(oldName.equals(newName)) { _pw.setDefaultMessage(); return; } PartName pn; try{ pn = PartName.parse(newName); // see if it is parsable }catch(RuntimeException pe) { _pw.showMessage("Not a valid part name. Name contains illegal characters"); _edgeNameText.requestFocus(); _edgeNameText.select(0,_edgeName.length()); return; } if(!newName.equals(pn.get_name().toString())) // see if parser accepted whole string as one thing { _pw.showMessage("Error: Parser interpreted differently"); _edgeNameText.requestFocus(); _edgeNameText.select(0,_edgeName.length()); return; } String from = _fromText.getText(); UID id = _editor.curDocument().net().nameToUID(from); UConstOrAltVertex u = (UConstOrAltVertex) _editor.curDocument().net().getNode(id); boolean found = u.checkThisOut(newName); if(found) // check if the edge name is already used for the source vertex { _pw.showMessage("Edge name already used"); _edgeNameText.requestFocus(); _edgeNameText.select(0,_edgeName.length()); return; } setEdgeName(newName); _panicName=newName; _editor.curDocument().damaged(_edge.get_persp()); } else if(source == _beforeText) // handle before syntax { String before = _beforeText.getText().trim(); if(before.length()>0) { _edge.set_beforeSyntax(before); _before = before; } else { _edge.set_beforeSyntax(null); _before=null; } } else { // handle after syntax String after = _afterText.getText().trim(); if(after.length()>0) { _edge.set_afterSyntax(after); _after = after; } else { _edge.set_afterSyntax(null); _after = null; } } _editor.curDocument().cdNeedsSaving(true); _pw.setDefaultMessage(); } public void focusGained(FocusEvent event){} public void focusLost(FocusEvent event) { Object source = event.getSource(); if(source == _edgeNameText) restoreName(); else if(source == _beforeText) restoreBefore(); else restoreAfter(); } private void restoreName() { _edgeNameText.setText(_edgeName); } private void restoreBefore() { if(_before==null) _beforeText.setText(""); else _beforeText.setText(_before); } private void restoreAfter() { if(_after==null) _afterText.setText(""); else _afterText.setText(_after); } public void setEdgeName(String name) { _edgeName = name; if(name == null) { _edgeNameText.setText("Not Applicable"); _edgeNameText.setEditable(false); _edgeNameText.setEnabled(false); } else { _edgeNameText.setText(name); _edgeNameText.setEditable(true); _edgeNameText.setEnabled(true); } ((FigConstEdge)_edge.get_persp().get_figure()).set_label(name); _edge.set_label(_editor.curDocument(),name); } public void itemStateChanged(ItemEvent event) { int index = _cardinalityChoice.getSelectedIndex(); switch (index) { case 0 : ((FigConstEdge)_edge.get_persp().get_figure()).set_cardinality("1"); setEdgeName(_panicName);break; case 1 : ((FigConstEdge)_edge.get_persp().get_figure()).set_cardinality("0..1"); setEdgeName(_panicName);break; case 2 : UVertex u = (UVertex) _edge.get_persp().get_sourcePerspective().owner(); if(u instanceof UAltVertex) { String cardinality = ((FigConstEdge)_edge.get_persp().get_figure()).get_cardinality(); if(cardinality.equals("1")) _cardinalityChoice.select(0); else _cardinalityChoice.select(1); _pw.showMessage("Abstract classes can't have repetition edges"); return; } if(u instanceof UConstVertex && _edgeName!=null) { if ( ((UConstVertex)u).isCrackingRepetition() ) { String cardinality = ((FigConstEdge)_edge.get_persp().get_figure()).get_cardinality(); if(cardinality.equals("1")) _cardinalityChoice.select(0); else _cardinalityChoice.select(1); _pw.showMessage("Repetition class can't have parts"); return; } } ((FigConstEdge)_edge.get_persp().get_figure()).set_cardinality("0..*"); setEdgeName(null);break; case 3 : UVertex v = (UVertex) _edge.get_persp().get_sourcePerspective().owner(); if(v instanceof UAltVertex) { String cardinality = ((FigConstEdge)_edge.get_persp().get_figure()).get_cardinality(); if(cardinality.equals("1")) _cardinalityChoice.select(0); else _cardinalityChoice.select(1); _pw.showMessage("Abstract classes can't have repetition edges"); return; } if(v instanceof UConstVertex && _edgeName!=null) { if ( ((UConstVertex)v).isCrackingRepetition() ) { String cardinality = ((FigConstEdge)_edge.get_persp().get_figure()).get_cardinality(); if(cardinality.equals("1")) _cardinalityChoice.select(0); else _cardinalityChoice.select(1); _pw.showMessage("Repetition class can't have parts"); return; } } ((FigConstEdge)_edge.get_persp().get_figure()).set_cardinality("1..*"); setEdgeName(null);break; } _editor.curDocument().damaged(_edge.get_persp()); _editor.curDocument().cdNeedsSaving(true); } } /* end class ConstEdgePanel */