package jaist.css.covis.cls; import jaist.css.covis.CoVisBuffer; import jaist.css.covis.PPPath; import jaist.css.covis.Selectable; import jaist.css.covis.hist.CVHist_Var; import java.awt.BasicStroke; import java.awt.Color; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.HashSet; import java.util.Hashtable; import java.util.TreeMap; import javax.swing.JFrame; import javax.swing.JOptionPane; import org.piccolo2d.PNode; import org.piccolo2d.nodes.PPath; import org.piccolo2d.nodes.PText; import org.piccolo2d.util.PDimension; public class Variable extends PPPath implements Layoutable, Selectable, ToFront, Move { public static BasicStroke roundrectStroke = new BasicStroke(6f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 90.0f); private static final long serialVersionUID = -2274392520995258292L; public Covis_Type cv_class; public Class<?> type; public Class<?> elementType; boolean isArray = false; // public Covis_Object cv_class_for_tooptip; // public static Variable selected_stamp; // public static ArrayList<Variable> stamps; // static{ // stamps = new ArrayList<Variable>(); // } private boolean isSelected; public boolean isEnabled = true; public Covis_Type object = null;// これがあるとMember PPath handle; PText caption; public Anchor anchor; private String varname_base; private HashSet<String> varnames; public CVHist_Var cvhist; long toFront_ts = 0; public CoVisBuffer buffer; public static float top = 0; public void setVarName_Base(String s) { varname_base = s; // varnames.add(s); } public boolean isEnabled() { return isEnabled; } public void setEnabled(boolean b) { isEnabled = b; anchor.setAnchorEnabled(b); } public Variable(Covis_Type co, JFrame frame, CoVisBuffer buf, boolean isMember) { cv_class = co; buffer = buf; varnames = new HashSet<String>(); if (cv_class instanceof Covis_Array) { // 型(クラス・プリミティブ)選択 String s; if (((Covis_Array) cv_class).elementClassStr == null) { s = (String) JOptionPane.showInputDialog( frame, "Choose Type of the Array", "Choose Type", JOptionPane.QUESTION_MESSAGE, null, ClassStamp.possibilities, Covis_Array.lastSelectedClass); if ((s != null) && (s.length() > 0)) { // System.out.println(s+" Selected."); Covis_Array.lastSelectedClass = s; } else { type = null; } } else { s = ((Covis_Array) cv_class).elementClassStr; } try { Class<?> c = Class.forName("jaist.css.covis.cls.Covis_" + s); Constructor<?> constructor = c.getConstructor(CoVisBuffer.class, boolean.class); cv_class = (Covis_Type) constructor.newInstance(buffer, true); type = Array.newInstance(c, 4).getClass(); elementType = cv_class.getClass(); System.out.println("array " + type.toString()); System.out.println("ele " + elementType.toString()); isArray = true; } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } else { type = cv_class.getClass(); elementType = type; } setPaint(cv_class.getClassColor()); setStrokePaint(Color.gray); setStroke(new BasicStroke(1)); // co.setScale(0.3f); // addChild(cv_class); // layout(0); addAttribute("info", "ClassStamp " + this.toString()); // addAttribute("selectable", this); addAttribute("moveTargetY", this); addAttribute("dragLayout", this); handle = new PPPath(this.getPathReference()); handle.addAttribute("moveTargetY", this); handle.addAttribute("dragLayout", this); handle.setTransparency(0.0f); handle.setPaint(Color.pink); handle.setStrokePaint(Color.red); handle.setStroke(roundrectStroke); handle.setPickable(true); handle.raiseToTop(); handle.addAttribute("info", "ClassStamp handle"); // handle.addAttribute("selectable", this); // handle.addAttribute("exclusiveSelectable", stamps); addChild(handle); if (!isMember) { varname_base = cv_class.getNextVarName(isArray); caption = new PText(getTypeName() + " " + varname_base); caption.scale(2.2f); caption.setOffset(10, 3); caption.addAttribute("moveTargetY", this); caption.addAttribute("dragLayout", this); addChild(caption); caption.addAttribute("popupMenu", new VariableMenu(this)); } if (cv_class instanceof Covis_Object || isArray) { anchor = new Anchor(type, this); anchor.setVarName(varname_base); addChild(anchor); anchor.setOffset(245, 30); if (!isMember) { anchor.setAnchorEnabled(true); } } else { // プリミティブなので,1つだけ追加 Covis_primitive prim = (Covis_primitive) cv_class; addChild(prim); prim.setPathToRectangle(0, 0, 30, (float) getHeight()); prim.setStroke(new BasicStroke(2)); prim.justify(); prim.setOffset(getWidth() - prim.getWidth(), (getHeight() - prim.getHeight()) / 2); prim.addAttribute("moveTargetY", this); prim.addAttribute("dragLayout", this); prim.valueText.addAttribute("moveTargetY", this); prim.valueText.addAttribute("dragLayout", this); prim.valueText.addAttribute("popupMenu", new VariableMenu(this)); } addAttribute("popupMenu", new VariableMenu(this)); handle.addAttribute("popupMenu", new VariableMenu(this)); // stamps.add(this); } public String getTypeName() { if (!isArray) { // if (type.isAssignableFrom(Covis_Object.class)){ return cv_class.getClsName(); } else { return cv_class.getClsName() + "[]"; } } public void layout(int dur) { layoutExceptOne(null, dur); } public void layoutExceptOne(PNode operationNode, int dur) { var col = getChildrenReference(); TreeMap<Integer, PNode> map = new TreeMap<Integer, PNode>(); for (var o : col) { PNode p = (PNode) o; map.put((int) p.getYOffset(), p); } double offsetx = 10; double endx = 10; double offsety = 10; double endy = 10; double maxx = 0, maxy = 0; for (PNode p : map.values()) { // p.setOffset(offsetx, offsety); double px = p.getFullBounds().width; double py = p.getFullBounds().height; if (maxx < offsetx + endx + px) maxx = offsetx + endx + px; if (maxy < offsety + endy + py) maxy = offsety + endy + py; if (operationNode != p) p.animateToPositionScaleRotation(offsetx, offsety + top, 1, 0, dur); offsety += py; offsety += 10; } animateToBounds(0, top, maxx, maxy, dur); } public ArrayList<Selectable> getAllChildren() { return null; } public boolean isSelected() { return isSelected; } public void setSelected(boolean f, ArrayList<Selectable> list) { isSelected = f; if (f) handle.setTransparency(0.8f); else handle.setTransparency(0.0f); if (f && list != null && !list.contains(this)) list.add(this); if (!f && list != null && list.contains(this)) list.remove(this); } public PNode theNode() { return this; } public void toggleSelected(ArrayList<Selectable> list) { setSelected(!isSelected, list); } public void removeLabel(Hashtable<PNode, PNode> trash) { if (trash != null) trash.put(this, getParent()); removeFromParent(); } // public PNode getToolTipNode(){ // if (cv_class_for_tooptip == null) { // cv_class_for_tooptip = cv_class.Covis_clone(); // cv_class_for_tooptip.setScale(0.5f); // } // return cv_class_for_tooptip; // } public String getBaseVarName() { return varname_base; } public void addVarNames(String prefix) { // System.out.println("Variable.addVarNames"+prefix); varnames.add(prefix); } public String getVarName() { StringBuffer sb = new StringBuffer(); for (String s : getVarNamesAry()) { sb.append(s + "\n"); } if (sb.length() == 0) return sb.toString(); return sb.toString().substring(0, sb.toString().length() - 1); } public ArrayList<String> getVarNamesAry() { ArrayList<String> news = new ArrayList<String>(); if (this instanceof VariableM) { String sepdot = "."; if (object instanceof Covis_Array) sepdot = ""; for (String s : varnames) { news.add(s + sepdot + varname_base); } } else { news.add(varname_base); } return news; } public void clearVarNamesAry() { varnames.clear(); } // この変数を削除する public void dispose() { if (anchor != null && anchor.destObject != null) { anchor.destObject.detach(anchor); } Layoutable layout = (Layoutable) getParent(); removeFromParent(); layout.layout(200); } // 変数名変更 public String rename(JFrame f) { String input; while (true) { if (isArray) { input = JOptionPane.showInputDialog(f, "Input new name for " + cv_class.getClsName() + "[] variable.", varname_base); } else { input = JOptionPane.showInputDialog(f, "Input new name for " + cv_class.getClsName() + " variable.", varname_base); } if (input == null) return null; if (input.equals("")) return null; // 変数名重複チェック // 親に聞くのが一番 VarField parent = (VarField) getParent(); if (parent.checkExistName(input, this)) { JOptionPane.showMessageDialog(null, "Same name is already used.\n\nPlease input other name.", "Rename Error", JOptionPane.WARNING_MESSAGE); continue; } if (!input.matches("^[a-zA-Z_][a-zA-Z0-9]*")) { JOptionPane.showMessageDialog(null, "Name should start with alphabet or _.\n\nPlease input other name.", "Rename Error", JOptionPane.WARNING_MESSAGE); continue; } break; } varname_base = input; if (anchor != null) { anchor.setVarName(varname_base); } caption.setText(getTypeName() + " " + varname_base); if (anchor != null && anchor.destObject != null) { anchor.destObject.tooltip = null; // 変数名ツールチップを再構築 } return varname_base; } public void toFront() { toFront(System.currentTimeMillis()); } public void toFront(long ts) { if (toFront_ts == ts) return; toFront_ts = ts; PNode parent = getParent(); if (parent != null) { // removeFromParent(); parent.addChild(this); if (parent instanceof ToFront) ((ToFront) parent).toFront(ts); } } public void move(PDimension d) { translate(d.getWidth(), d.getHeight()); // 履歴に関係ない動作 if (anchor != null) anchor.start_RewindThread(); } public String getConstructorInfo() { if (cv_class instanceof Covis_Object || isArray) return getTypeName() + " " + varname_base + ";"; else return getTypeName() + " " + varname_base + " = " + ((Covis_primitive) cv_class).value + ";"; // getValue()にすると,''がとれてしまうので } public void setCVHist(CVHist_Var _cvhist) { cvhist = _cvhist; } public String getEditValueInfo() { if (cv_class instanceof Covis_Object || isArray) return getTypeName() + " " + varname_base + ";"; else return varname_base + " = " + ((Covis_primitive) cv_class).value + ";"; // getValue()にすると,''がとれてしまうので } public void appendVarNameRecursive(Hashtable<Integer, Object> checked) { // System.out.println(varname_base); if (anchor == null) return; if (anchor.destObject != null) { // if (checked.containsKey(this.hashCode())) return; // checked.put(this.hashCode(), this); // System.out.println("V append "+getVarName()); anchor.destObject.appendVarNameRecursive(this, checked); } } public static String getShortestName(ArrayList<String> src) { if (src.size() == 0) return null; if (src.size() == 1) return src.get(0); String temp = src.get(0); for (String s : src) { if (s.length() < temp.length()) temp = s; } return temp; } }