package com.jpaulmorrison.graphics; import java.awt.*; import java.awt.event.*; import java.io.*; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.*; import javax.swing.*; import com.jpaulmorrison.graphics.DrawFBP.GenLang; public class Block implements ActionListener { String type; // One of Types (single character strings) DrawFBP driver; int leftEdge, rgtEdge, topEdge, botEdge; int width, height; String description; //String descMod; // modified a lot for .fbp notation; slightly, for other notations (" -> _) String diagramFileName; String fullClassName; // (file name plus class name) or NoFlo name (now // shifted to codeFileName) int cx, cy; // coords of centre // int x, y; // used for dragging // int sdcx, sdcy; // center before adjustment int id; int tlx, tly; static final int BLOCKWIDTH = 92; // was 76; static final int BLOCKHEIGHT = 64; // was 52; boolean multiplex = false; boolean deleteOnSave = false; Diagram diag; LegendBlock lblk; String mpxfactor = null; HashMap<String, AInPort> inputPortAttrs; HashMap<String, AOutPort> outputPortAttrs; int scan_pos = 0; Block vNeighbour, hNeighbour; // block at same position, vert. or horiz. boolean visible = true; /* next four fields are not stored in .drw files */ URLClassLoader classLoader = null; Class<?> javaClass; // selected Java class for block (fullClassName is equivalent in String format) String compDescr; // used for annotations only boolean isSubnet; //JMenuItem[] sMenu; Color lg = new Color(240, 240, 240); // very light gray Color ly = new Color(255, 255, 200); // light yellow Color lb = new Color(200, 255, 255); // light blue (turquoise actually) Color grey = new Color(170, 244, 255); // sort of grey (?) int ROWSIZE = 5; String codeFileName; HashMap<String, Integer> portlist; static public class Types { static String PROCESS_BLOCK = "B"; static String EXTPORT_IN_BLOCK = "C"; static String EXTPORT_OUT_BLOCK = "D"; static String EXTPORT_OUTIN_BLOCK = "E"; static String FILE_BLOCK = "F"; static String IIP_BLOCK = "I"; static String LEGEND_BLOCK = "L"; static String ENCL_BLOCK = "O"; static String PERSON_BLOCK = "P"; static String REPORT_BLOCK = "R"; } Block(Diagram d) { diag = d; driver = d.driver; type = Block.Types.PROCESS_BLOCK; diagramFileName = null; fullClassName = null; d.maxBlockNo ++; id = d.maxBlockNo; // HashMap<String, String> associatedCode = null; } void draw(Graphics2D g) { if (diag == null) // fudge return; if (!visible && this != driver.selBlock) { showZones(g); return; } if (this == driver.selBlock && !(this instanceof ProcessBlock)) { showArrowEndAreas(g); return; } int tlx = cx - width / 2; int tly = cy - height / 2; g.setFont(driver.fontg); calcDiagMaxAndMin(tlx - 20, cx + width / 2 + 20, cy - height / 2, cy + height / 2 + 40); g.setColor(Color.BLACK); g.drawRoundRect(tlx, tly, width, height, 6, 6); if (this == driver.selBlock) g.setColor(ly); // light yellow else g.setColor(lb); // light turquoise g.fillRoundRect(tlx + 1, tly + 1, width - 1, height - 1, 6, 6); if (multiplex) { int x, y; String s = mpxfactor; if (s == null) s = " "; int i = s.length() * driver.gFontWidth + 10; x = tlx - i; y = cy - 20 / 2; g.setColor(Color.BLACK); g.drawRoundRect(x, y, i - 1, 20, 2, 2); if (this == driver.selBlock) g.setColor(ly); // light yellow else g.setColor(lb); // light turquoise g.fillRoundRect(x + 1, y + 1, i - 2, 19, 2, 2); g.setColor(Color.BLACK); if (mpxfactor != null) g.drawString(mpxfactor, x + 5, y + 15); } g.setColor(Color.BLACK); // if composite, draw with an inner outline // if (diagramFileName != null) if (isSubnet) // block is a subnet g.drawRoundRect(tlx + 2, tly + 2, width - 4, height - 4, 6, 6); // g.drawLine(tlx, tly + driver.fontHeight + driver.fontHeight // / 2 + // 3, tlx + // width, // tly + driver.fontHeight + driver.fontHeight / 2 + 3); // showZones(g); if (description != null) { centreDesc(g); } if (!visible && this == driver.selBlock) g.drawLine(tlx, tly, cx + width / 2, cy + height / 2); int y = cy + height / 2 + driver.gFontHeight + driver.gFontHeight / 2; if (diagramFileName != null) { Font fontsave = g.getFont(); g.setFont(driver.fontf); g.setColor(Color.GRAY); File gFile = new File(diagramFileName); String name = gFile.getName(); int x = cx - name.length() * driver.gFontWidth / 2; g.drawString(name, x, y); g.setFont(fontsave); y += driver.gFontHeight; calcDiagMaxAndMin(x - 20, x + name.length() * driver.gFontWidth + 20, cy - height / 2, y + 40); } String name = null; if (diag.diagLang != null && diag.diagLang.label.equals("Java")) { if (javaClass != null) { Font fontsave = g.getFont(); g.setFont(driver.fontf); g.setColor(Color.BLUE); name = javaClass.getSimpleName() + ".class"; int x = cx - name.length() * driver.gFontWidth / 2; g.drawString(name, x, y); g.setFont(fontsave); y += driver.gFontHeight; calcDiagMaxAndMin(x - 20, x + name.length() * driver.gFontWidth + 20, cy - height / 2, y + 40); } else if (fullClassName != null) { Font fontsave = g.getFont(); g.setFont(driver.fontf); name = "Class not found or out of date - rechoose comp/subnet"; // ?????????????????? int x = cx - name.length() * driver.gFontWidth / 2; g.drawString(name, x, y); g.setFont(fontsave); y += driver.gFontHeight; name = fullClassName; g.setColor(Color.RED); x = cx - name.length() * driver.gFontWidth / 2; g.drawString(name, x, y); g.setFont(fontsave); g.setColor(Color.BLACK); y += driver.gFontHeight; calcDiagMaxAndMin(x - 20, x + name.length() * driver.gFontWidth + 20, cy - height / 2, y + 40); } } if (codeFileName != null) { Font fontsave = g.getFont(); g.setFont(driver.fontf); name = codeFileName; int i = name.lastIndexOf(File.separator); if (i == -1) i = name.lastIndexOf("/"); name = name.substring(i + 1); g.setColor(Color.BLACK); int x = cx - name.length() * driver.gFontWidth / 2; g.drawString(name, x, y); g.setFont(fontsave); g.setColor(Color.BLACK); calcDiagMaxAndMin(x - 20, x + name.length() * driver.gFontWidth + 20, cy - height / 2, y + 40); } if (hNeighbour != null) { g.setColor(Color.ORANGE); if (hNeighbour.cx < cx) g.drawLine(hNeighbour.cx - hNeighbour.width / 2, hNeighbour.cy + hNeighbour.height / 2, cx + width / 2, hNeighbour.cy + hNeighbour.height / 2); else g.drawLine(hNeighbour.cx + hNeighbour.width / 2, hNeighbour.cy + hNeighbour.height / 2, cx - width / 2, hNeighbour.cy + hNeighbour.height / 2); g.setColor(Color.BLACK); } if (vNeighbour != null) { g.setColor(Color.ORANGE); if (vNeighbour.cy < cy) g.drawLine(vNeighbour.cx - vNeighbour.width / 2, vNeighbour.cy - vNeighbour.height / 2, vNeighbour.cx - vNeighbour.width / 2, cy + height / 2); else g.drawLine(vNeighbour.cx - vNeighbour.width / 2, vNeighbour.cy + vNeighbour.height / 2, vNeighbour.cx - vNeighbour.width / 2, cy - height / 2); g.setColor(Color.BLACK); } if (driver.arrowRoot != null && driver.arrowRoot.b == this) { if (driver.arrowEndForDragging == null || !driver.arrowEndForDragging.headMarked && !driver.arrowEndForDragging.tailMarked) { Enclosure enc = null; if (type == Block.Types.ENCL_BLOCK) enc = (Enclosure) this; if (enc == null || enc.corner == null) { Color col = g.getColor(); g.setColor(Color.BLUE); g.drawOval(driver.arrowRoot.x - 4, driver.arrowRoot.y - 4, 8, 8); g.setColor(col); } } } } void calcEdges() { leftEdge = cx - width / 2; rgtEdge = cx + width / 2; topEdge = cy - height / 2; botEdge = cy + height / 2; } void calcDiagMaxAndMin(int xmin, int xmax, int ymin, int ymax) { //if (visible) { diag.maxX = Math.max(xmax + 20, diag.maxX); diag.minX = Math.min(xmin - 20, diag.minX); diag.maxY = Math.max(ymax, diag.maxY); diag.minY = Math.min(ymin - 20, diag.minY); //} } void centreDesc(Graphics2D g) { g.setColor(Color.BLACK); int x = 0; int y = 0; int minX = Integer.MAX_VALUE; int maxX = 0; String str[] = description.split("\n"); boolean nonBlankLineFound = false; FontMetrics metrics = g.getFontMetrics(g.getFont()); for (int i = 0; i < str.length; i++) { x = 0; for (int j = 0; j < str[i].length(); j++) { char c = str[i].charAt(j); if (c != ' ') minX = Math.min(x, minX); x += metrics.charWidth(c); } maxX = Math.max(x, maxX); if (!(str[i].trim().equals(""))) { // minY = Math.min(minY, y); y += driver.gFontHeight; nonBlankLineFound = true; } if (nonBlankLineFound) { // maxY = y; } } x = (maxX - minX) / 2; // find half width x = cx - x; y = y / 2; // find half height if (this instanceof ReportBlock) y = cy - y; else if (this instanceof PersonBlock) y = cy + height / 2 + driver.gFontHeight; else y = cy - y + driver.gFontHeight; y -= driver.gFontHeight / 3; // fudge! int saveY = y; for (int i = 0; i < str.length; i++) { g.drawString(str[i], x, y); y += driver.gFontHeight; } if (this instanceof LegendBlock) { height = y - saveY + 24; width = maxX - minX + 24; // calcEdges(); } } void showZones(Graphics2D g) { if (diag.currentArrow == null) { if (driver.selBlockM == this) showArrowEndAreas(g); } else if (diag.currentArrow.fromId != id) showArrowEndAreas(g); } String serialize() { String s = "<block> <x> " + cx + " </x> <y> " + cy + " </y> <id> " + id + " </id> <type>" + type + "</type> "; s += "<width>" + width + "</width> <height>" + height + "</height> "; if (description != null) { s += "<description>"; for (int i = 0; i < description.length(); i++) { if (description.charAt(i) == '<' || description.charAt(i) == '>') { s += '\\'; // protect the angle bracket } s += description.charAt(i); } s += "</description> "; } if (diagramFileName != null) { //String relDiagFileName = DrawFBP.makeRelFileName(diagramFileName, // diag.diagFile.getAbsolutePath()); s += "<diagramfilename>" + diagramFileName + "</diagramfilename> "; } if (codeFileName != null) { //String relCodeFileName = DrawFBP.makeRelFileName(codeFileName, // diag.diagFile.getAbsolutePath()); s += "<codefilename>" + codeFileName + "</codefilename> "; } if (fullClassName != null) { String t = fullClassName; if (t.toLowerCase().endsWith(".class")) t = t.substring(0, t.length() - 6); s += "<blockclassname>" + t + "</blockclassname> "; } if (this instanceof ExtPortBlock) { ExtPortBlock eb = (ExtPortBlock) this; //if (eb.substreamSensitive) s += "<substreamsensitive>" + (eb.substreamSensitive?"true":"false") + "</substreamsensitive>"; } // if (multiplex) s += "<multiplex>" + (multiplex?"true":"false") + "</multiplex>"; //if (!visible) s += "<invisible>" + (!visible?"true":"false") + "</invisible>"; s += "<issubnet>" + (isSubnet?"true":"false") + "</issubnet> \n" ; if (mpxfactor != null) s += "<mpxfactor>" + mpxfactor + "</mpxfactor> \n"; if (this instanceof Enclosure) { Enclosure ol = (Enclosure) this; // if (ol.description != null) // s += "<description>" + ol.description + "</description> "; s += "\n"; s += "<subnetports>"; for (SubnetPort snp : ol.subnetPorts) { s += "<subnetport> <y>" + snp.y + "</y>"; if (snp.name != null) s += " <name>" + snp.name + "</name>"; String side = (snp.side == DrawFBP.Side.LEFT) ? "L" : "R"; s += " <side>" + side + "</side>"; //if (snp.substreamSensitive) s += "<substreamsensitive>" + (snp.substreamSensitive?"true":"false") + "</substreamsensitive>"; s += "</subnetport> \n"; } s += "</subnetports>"; } s += "</block> \n"; return s; } void buildBlockFromXML(HashMap<String, String> item) { // Build a block using a HashMap built using the XML description String s; type = item.get("type"); description = item.get("description"); if (type.equals("I") && description != null && description.substring(0,1).equals("\"")) description = description.substring(1,description.length() - 1); if (type == null) type = Block.Types.PROCESS_BLOCK; codeFileName = item.get("codefilename"); //if (codeFileName != null) { // codeFileName = DrawFBP.makeAbsFileName(codeFileName, // diag.diagFile.getAbsolutePath()); // diag.changeCompLang(); //} diagramFileName = item.get("diagramfilename"); if (diagramFileName != null) isSubnet = true; s = item.get("issubnet"); if (s != null) isSubnet = s.equals("true"); fullClassName = item.get("blockclassname"); getClassInfo(fullClassName); s = item.get("x").trim(); cx = Integer.parseInt(s); s = item.get("y").trim(); cy = Integer.parseInt(s); s = item.get("id").trim(); id = Integer.parseInt(s); s = item.get("width"); width = Integer.parseInt(s.trim()); s = item.get("height"); if (s != null) height = Integer.parseInt(s.trim()); s = item.get("multiplex"); if (s != null) multiplex = true; s = item.get("mpxfactor"); if (s != null) mpxfactor = s; s = item.get("invisible"); if (s != null) visible = false; if (this instanceof Enclosure) { Enclosure ol = (Enclosure) this; ol.description = item.get("description"); } calcEdges(); diag.maxBlockNo = Math.max(id, diag.maxBlockNo); // driver.frame.setSize(driver.maxX, driver.maxY); if (this instanceof ProcessBlock && javaClass != null) { buildMetadata(); } } void getClassInfo(String fcn){ fullClassName = fcn; //fullClassName = item.get("blockclassname"); if (fullClassName != null) { if (fullClassName.indexOf("!") == -1) {// if no "!", language is not // Java... driver.tryFindJarFile = false; if (fullClassName.toLowerCase().endsWith(".json")) { codeFileName = fullClassName; fullClassName = null; } return; } if (driver.tryFindJarFile) { if (!driver.getJavaFBPJarFile()) { MyOptionPane .showMessageDialog( driver.frame, "Unable to read JavaFBP jar file - " + "so cannot process class information for " + description, MyOptionPane.ERROR_MESSAGE); driver.tryFindJarFile = false; } else loadClass(); } // diag.compLang = driver.findGLFromLabel("Java"); } } void loadClass(){ int i = fullClassName.indexOf("!"); if (i == -1) return; String fn = fullClassName.substring(0, i); // jar file name or class folder String cn = fullClassName.substring(i + 1); // class name //LinkedList<URL> ll = new LinkedList<URL>(); if (!(fn.endsWith("jar"))) fn += File.separator; File f = new File(fn); URL[] urls = buildUrls(f); if (urls == null) javaClass = null; else try { classLoader = new URLClassLoader(urls); javaClass = classLoader.loadClass(cn); } catch (ClassNotFoundException e) { //System.out.println("Missing class name in " + fullClassName); MyOptionPane.showMessageDialog(driver.frame, "Class name not found: " + fullClassName, MyOptionPane.ERROR_MESSAGE); // e.printStackTrace(); javaClass = null; } catch (NoClassDefFoundError e) { //System.out.println("Missing internal class name in " // + fullClassName); MyOptionPane.showMessageDialog(driver.frame, "Internal class name not found: " + fullClassName, MyOptionPane.ERROR_MESSAGE); // e.printStackTrace(); javaClass = null; } } Class<?> getSelectedClass(String jar, String jf, boolean injar) { if (jf.trim().equals("")) { return null; } //tentative... String fn = ""; if (injar) { fn = jar; if (fn.lastIndexOf("javafbp") == -1){ fn = driver.javaFBPJarFile; } } else fn = driver.javaFBPJarFile; int j = fn.lastIndexOf("javafbp") + 8; String seg = "engine."; if (0 <= fn.substring(j, j + 1).compareTo("4")) // if javafbp jar file version not less than 4.0.0 seg = "core.engine."; String owner = "jpmorrsn"; if (0 <= fn.substring(j, j + 3).compareTo("4.1")) // if javafbp jar file version not less than 4.0.0 owner = "jpaulmorrison"; Class<?> cls; try { Class<?> compClass = classLoader .loadClass("com." + owner + ".fbp." + seg + "Component"); Class<?> networkClass = classLoader .loadClass("com." + owner + ".fbp." + seg + "Network"); Class<?> subnetClass = classLoader .loadClass("com." + owner + ".fbp." + seg + "SubNet"); int i = jf.lastIndexOf(".class"); if (i != -1) jf = jf.substring(0, i); jf = jf.replace('/', '.'); cls = classLoader.loadClass(jf); if (cls.getCanonicalName().equals(compClass.getCanonicalName()) || cls.getCanonicalName().equals(networkClass.getCanonicalName()) || cls.getCanonicalName().equals(subnetClass.getCanonicalName())){ return null; } Class<?> cs = cls.getSuperclass(); if (cs == null || !(cs.getCanonicalName().equals(compClass.getCanonicalName()) || cs.getCanonicalName().equals(subnetClass.getCanonicalName()))) { MyOptionPane.showMessageDialog(driver.frame, "Class file not a valid FBP component", MyOptionPane.ERROR_MESSAGE); return null; } boolean mainPresent = true; try { cls.getMethod("main", String[].class); } catch (NoSuchMethodException e) { mainPresent = false; } catch (NoClassDefFoundError e) { mainPresent = false; } catch (SecurityException e2) { mainPresent = false; } if (mainPresent) { MyOptionPane.showMessageDialog(driver.frame, "Class file contains a 'main' method", MyOptionPane.ERROR_MESSAGE); return null; } else { //this.classLoader = classLoader; return cls; } } catch (ClassNotFoundException e) { System.err.println("Class not found exception:"); e.printStackTrace(); return null; } } void showArrowEndAreas(Graphics2D g) { g.setColor(grey); g.fillRect(cx - width / 2 - 1, cy - height / 2 - 1, 4, height); // left if (!(this instanceof Enclosure)) g.fillRect(cx - width / 2 - 1, cy - height / 2 - 1, width + 3, 4); // top if (!(this instanceof ReportBlock)) { g.fillRect(cx - width / 2 - 1, cy + height / 2 - 2, width + 3, 4); // bottom g.fillRect(cx + width / 2 - 1, cy - height / 2 - 1, 4, height); // right } else g.fillRect(cx + width / 2 - 1, cy - height / 2 - 1, 4, height - 12); // right g.setColor(Color.BLACK); } void buildMetadata() { inputPortAttrs = new HashMap<String, AInPort>(); outputPortAttrs = new HashMap<String, AOutPort>(); String s = driver.javaFBPJarFile; int j = s.lastIndexOf("javafbp") + 8; String seg = "engine."; if (0 <= s.substring(j, j + 1).compareTo("4")) // if javafbp jar file version not less than 4.0.0 seg = "core.engine."; String owner = "jpmorrsn"; if (0 <= s.substring(j, j + 3).compareTo("4.1")) // if javafbp jar file version not less than 4.0.0 owner = "jpaulmorrison"; try { Class<?> compdescCls = classLoader .loadClass("com." + owner + ".fbp." + seg + "ComponentDescription"); Class<?> inportCls = classLoader .loadClass("com." + owner + ".fbp." + seg + "InPort"); Class<?> outportCls = classLoader .loadClass("com." + owner + ".fbp." + seg + "OutPort"); Class<?> inportsCls = classLoader .loadClass("com." + owner + ".fbp." + seg + "InPorts"); Class<?> outportsCls = classLoader .loadClass("com." + owner + ".fbp." + seg + "OutPorts"); Annotation[] annos = javaClass.getAnnotations(); for (Annotation a : annos) { if (compdescCls.isInstance(a)) { Method meth = compdescCls.getMethod("value"); compDescr = (String) meth.invoke(a); } if (inportCls.isInstance(a)) { getInPortAnnotation(a, inportCls); } if (inportsCls.isInstance(a)) { Method meth = inportsCls.getMethod("value"); Object[] oa = (Object[]) meth.invoke(a); for (Object o : oa) { getInPortAnnotation((Annotation) o, inportCls); } } if (outportCls.isInstance(a)) { getOutPortAnnotation(a, outportCls); } if (outportsCls.isInstance(a)) { Method meth = outportsCls.getMethod("value"); Object[] oa = (Object[]) meth.invoke(a); for (Object o : oa) { getOutPortAnnotation((Annotation) o, outportCls); } } } } catch (Exception e) { e.printStackTrace(); } } void getInPortAnnotation(Annotation a, Class<?> inport) { AInPort ipt = new AInPort(); try { Method meth = inport.getMethod("value"); ipt.value = (String) meth.invoke(a); meth = inport.getMethod("arrayPort"); Boolean b = (Boolean) meth.invoke(a); ipt.arrayPort = b.booleanValue(); meth = inport.getMethod("fixedSize"); b = (Boolean) meth.invoke(a); ipt.fixedSize = b.booleanValue(); meth = inport.getMethod("optional"); b = (Boolean) meth.invoke(a); ipt.optional = b.booleanValue(); meth = inport.getMethod("description"); ipt.description = (String) meth.invoke(a); meth = inport.getMethod("type"); ipt.type = (Class<?>) meth.invoke(a); meth = inport.getMethod("setDimension"); Integer ic = (Integer) meth.invoke(a); int i = ic.intValue(); meth = inport.getMethod("valueList"); String[] sa = (String[]) meth.invoke(a); for (String s : sa) { if (s.toLowerCase().endsWith("*")) { for (int j = 0; j < i; j++) { AInPort ipt2 = new AInPort(); ipt2.value = s.substring(0, s.length() - 1) + j; ipt2.arrayPort = ipt2.arrayPort; ipt2.fixedSize = ipt.fixedSize; ipt2.description = ipt.description; ipt2.optional = ipt.optional; ipt2.type = ipt.type; inputPortAttrs.put(ipt2.value, ipt2); } } else { AInPort ipt2 = new AInPort(); ipt2.value = s; ipt2.arrayPort = ipt2.arrayPort; ipt2.fixedSize = ipt.fixedSize; ipt2.description = ipt.description; ipt2.optional = ipt.optional; ipt2.type = ipt.type; inputPortAttrs.put(ipt2.value, ipt2); } } if (sa.length == 0) inputPortAttrs.put(ipt.value, ipt); } catch (Exception e) { e.printStackTrace(); } } AOutPort getOutPortAnnotation(Annotation a, Class<?> outport) { AOutPort opt = new AOutPort(); try { Method meth = outport.getMethod("value"); opt.value = (String) meth.invoke(a); meth = outport.getMethod("arrayPort"); Boolean b = (Boolean) meth.invoke(a); opt.arrayPort = b.booleanValue(); meth = outport.getMethod("fixedSize"); b = (Boolean) meth.invoke(a); opt.fixedSize = b.booleanValue(); meth = outport.getMethod("optional"); b = (Boolean) meth.invoke(a); opt.optional = b.booleanValue(); meth = outport.getMethod("description"); opt.description = (String) meth.invoke(a); meth = outport.getMethod("type"); opt.type = (Class<?>) meth.invoke(a); meth = outport.getMethod("setDimension"); Integer ic = (Integer) meth.invoke(a); int i = ic.intValue(); meth = outport.getMethod("valueList"); String[] sa = (String[]) meth.invoke(a); for (String s : sa) { if (s.toLowerCase().endsWith("*")) { for (int j = 0; j < i; j++) { AOutPort opt2 = new AOutPort(); opt2.value = s.substring(0, s.length() - 1) + j; opt2.arrayPort = opt2.arrayPort; opt2.fixedSize = opt.fixedSize; opt2.optional = opt.optional; opt2.description = opt.description; opt2.type = opt.type; outputPortAttrs.put(opt2.value, opt2); } } else { AOutPort opt2 = new AOutPort(); opt2.value = s; opt2.arrayPort = opt2.arrayPort; opt2.fixedSize = opt.fixedSize; opt2.optional = opt.optional; opt2.description = opt.description; opt2.type = opt.type; outputPortAttrs.put(opt2.value, opt2); } } if (sa.length == 0) outputPortAttrs.put(opt.value, opt); } catch (Exception e) { e.printStackTrace(); } return opt; } void displayPortInfo() { buildMetadata(); final JDialog jdialog = new JDialog(driver.frame); jdialog.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent ev) { jdialog.dispose(); } }); jdialog.setTitle("Description and Port Information"); jdialog.toFront(); JPanel panel = new JPanel(new GridBagLayout()); panel.setBackground(Color.GRAY); GridBagLayout gbl = new GridBagLayout(); GridBagConstraints gbc = new GridBagConstraints(); panel.setLayout(gbl); gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 0.5; gbc.weighty = 0.5; gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = ROWSIZE; String desc = description.replace('\n', ' '); JTextField tfd = new JTextField(" " + desc + " "); Font ft = tfd.getFont(); ft = ft.deriveFont(Font.BOLD); tfd.setFont(ft); tfd.setForeground(Color.BLUE); tfd.setEditable(false); gbl.setConstraints(tfd, gbc); //tfd.setBackground(lg); panel.add(tfd); int i = fullClassName.indexOf("!"); String s1 = fullClassName.substring(0, i); String s2 = fullClassName.substring(i + 1); gbc.gridy = 1; JTextField tf0 = new JTextField(" " + s1 + " "); tf0.setEditable(false); gbl.setConstraints(tf0, gbc); tf0.setBackground(lg); panel.add(tf0); gbc.gridy = 2; JTextField tf1 = new JTextField(" " + s2 + " "); tf1.setForeground(Color.BLUE); tf1.setEditable(false); gbl.setConstraints(tf1, gbc); tf1.setBackground(lg); panel.add(tf1); gbc.weightx = 1.5; gbc.weighty = 0.5; gbc.gridx = 0; gbc.gridy = 3; gbc.gridwidth = ROWSIZE; if (compDescr == null || compDescr.equals("")) { compDescr = "(no description)"; } JTextField tf2 = new JTextField(compDescr); tf2.setEditable(false); gbl.setConstraints(tf2, gbc); tf2.setBackground(lg); panel.add(tf2); gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 0.5; gbc.gridwidth = 1; gbc.gridy = 4; JTextField[] tft = new JTextField[ROWSIZE]; tft[0] = new JTextField(" Port "); tft[1] = new JTextField(" Type "); tft[2] = new JTextField(" Class "); tft[3] = new JTextField(" Function "); tft[4] = new JTextField(" Connected? "); displayRow(gbc, gbl, tft, panel, Color.BLUE); for (AInPort ip : inputPortAttrs.values()) { JTextField[] tfi = new JTextField[ROWSIZE]; tfi[0] = new JTextField(ip.value); String s = "input"; if (ip.arrayPort) s += ", array"; if (ip.fixedSize) s += ", fixed size"; if (ip.optional) s += ", optional"; tfi[1] = new JTextField(s); if (ip.type == null) tfi[2] = new JTextField(""); else tfi[2] = new JTextField(ip.type.getName()); tfi[3] = new JTextField(ip.description); int res = testMatch(tfi[0].getText(), tfi[1].getText()); String results[] = {"Yes", "Missing", "Optional"}; tfi[4] = new JTextField(results[res]); gbc.gridx = 0; gbc.weightx = 0.5; displayRow(gbc, gbl, tfi, panel, Color.BLACK); } for (AOutPort op : outputPortAttrs.values()) { JTextField[] tfo = new JTextField[ROWSIZE]; tfo[0] = new JTextField(op.value); String s = "output"; if (op.arrayPort) s += ", array"; if (op.fixedSize) s += ", fixed size"; if (op.optional) s += ", optional"; tfo[1] = new JTextField(s); if (op.type == null) tfo[2] = new JTextField(""); else tfo[2] = new JTextField(op.type.getName()); tfo[3] = new JTextField(op.description); int res = testMatch(tfo[0].getText(), tfo[1].getText()); String results[] = {"Yes", "Missing", "Optional"}; tfo[4] = new JTextField(results[res]); displayRow(gbc, gbl, tfo, panel, Color.BLACK); } LinkedList<String> lst = checkUnmatchedPorts(); for (String ls : lst) { JTextField[] tfu = new JTextField[ROWSIZE]; tfu[0] = new JTextField(ls.substring(1)); if (ls.substring(0, 1).equals("I")) tfu[1] = new JTextField("(input)"); else tfu[1] = new JTextField("(output)"); tfu[2] = new JTextField(""); tfu[3] = new JTextField(""); tfu[4] = new JTextField("?"); displayRow(gbc, gbl, tfu, panel, Color.BLACK); } jdialog.add(panel); //jdialog.pack(); Point p = driver.frame.getLocation(); Dimension dim = driver.frame.getSize(); //int x_off = 100; //int y_off = 100; //jdialog.setPreferredSize(new Dimension(dim.width - x_off, dim.height - y_off)); //jdialog.pack(); //int height = 200 + inputPortAttrs.size() * 40 + outputPortAttrs.size() * 40; int width = (int)jdialog.getPreferredSize().getWidth(); int max_y = 0; for (Block b: driver.curDiag.blocks.values()) { max_y = Math.max(max_y, b.cy + b.height / 2 ); } jdialog.pack(); //jdialog.setLocation(p.x + dim.width / 2 - width / 2, p.y + dim.height - height - y_off); jdialog.setLocation(p.x + dim.width / 2 - width / 2, p.y + max_y + 50); panel.setVisible(true); jdialog.setVisible(true); jdialog.toFront(); //jdialog.setPreferredSize(new Dimension(dim.width / 2, dim.height / 2)); jdialog.validate(); panel.repaint(); jdialog.repaint(); driver.frame.repaint(); } void displayRow(GridBagConstraints gbc, GridBagLayout gbl, JTextField[] tf, JPanel panel, Color col) { gbc.gridx = 0; gbc.weightx = 0.5; for (int i = 0; i < ROWSIZE; i++) { if (i == ROWSIZE - 1) gbc.weightx = 0.75; gbl.setConstraints(tf[i], gbc); tf[i].setBackground(lg); tf[i].setForeground(col); gbc.gridx++; panel.add(tf[i]); tf[i].setEditable(false); } gbc.gridy++; } int testMatch(String port, String type) { // this logic is somewhat over-constrained! // this routine returns a value of 0, 1 or 2 (Yes, Missing or Optional) boolean input = (type.indexOf("in") > -1 || type.indexOf("param") > -1); boolean output = (type.indexOf("out") > -1); if (!input && !output) { MyOptionPane.showMessageDialog(driver.frame, "Port type of \"" + port + "\" must be \"in\" or \"out\"", MyOptionPane.ERROR_MESSAGE); return 1; } for (Arrow arrow : diag.arrows.values()) { //if (arrow.endsAtLine) // continue; Arrow arr = arrow.findArrowEndingAtBlock(); if (arr == null) return 2; if (id == arr.toId && arr.downStreamPort != null && stem(arr.downStreamPort).equals(port)) if (input) return 0; else return 1; if (id == arrow.fromId && arrow.upStreamPort != null && stem(arrow.upStreamPort).equals(port)) if (output) return 0; else return 1; } //if (input) // return 3; // If input port missing, that's OK //else if (type.indexOf("optional") > -1) // return 2; //else // return 1; // If output port missing, error //if (input) // return 3; // If input port missing, that's OK //else if (type.indexOf("optional") > -1) return 2; else return 1; // If port missing, error } LinkedList<String> checkUnmatchedPorts() { LinkedList<String> lst = new LinkedList<String>(); for (Arrow arrow : diag.arrows.values()) { if (arrow.endsAtLine) continue; boolean found = false; if (arrow.downStreamPort != null && !arrow.downStreamPort.equals("*") && id == arrow.toId) { for (AInPort ip : inputPortAttrs.values()) { if (ip.value.equals(stem(arrow.downStreamPort))) { found = true; break; } } if (!found) lst.add("I" + arrow.downStreamPort); } if (arrow.upStreamPort != null && !arrow.upStreamPort.equals("*") && id == arrow.fromId) { for (AOutPort op : outputPortAttrs.values()) { if (op.value.equals(stem(arrow.upStreamPort))) { found = true; break; } } if (!found) lst.add("O" + arrow.upStreamPort); } } return lst; } String stem(String s) { int i = s.indexOf("["); if (i == -1) return s; else return s.substring(0, i); } void buildBlockPopupMenu() { diag.jpm = new JPopupMenu(" Block-related Actions"); // driver.curPopup = jpm; diag.jpm.setLocation(cx + 100, cy + 100); diag.jpm.setVisible(true); JMenuItem menuItem = null; JLabel label2 = new JLabel(); label2.setFont(driver.fontg); // label2.setHorizontalAlignment(SwingConstants.CENTER); label2.setText(diag.jpm.getLabel()); // label2.setForeground(Color.BLUE); diag.jpm.add(label2); diag.jpm.addSeparator(); //int j = driver.genLangs.length; //sMenu = new JMenuItem[j]; //for (int i = 0; i < j; i++) { // sMenu[i] = new JMenuItem(driver.genLangs[i].label); //} if (this instanceof Enclosure) { menuItem = new JMenuItem("Edit Subnet Label"); menuItem.addActionListener(this); diag.jpm.add(menuItem); menuItem = new JMenuItem("Edit Subnet Port Name"); menuItem.addActionListener(this); diag.jpm.add(menuItem); menuItem = new JMenuItem("Toggle Substream Sensitivity"); menuItem.addActionListener(this); diag.jpm.add(menuItem); diag.jpm.addSeparator(); menuItem = new JMenuItem("Excise Subnet"); menuItem.addActionListener(this); diag.jpm.add(menuItem); diag.jpm.addSeparator(); menuItem = new JMenuItem("Drag Contents"); menuItem.addActionListener(this); diag.jpm.add(menuItem); } else { if (this instanceof ProcessBlock || this instanceof FileBlock || this instanceof ReportBlock || this instanceof LegendBlock) { if (this instanceof ProcessBlock) menuItem = new JMenuItem("Edit Process Name or Description"); else menuItem = new JMenuItem("Edit Description"); menuItem.addActionListener(this); diag.jpm.add(menuItem); if (this instanceof ProcessBlock) { menuItem = new JMenuItem("Toggle Subnet On/Off"); menuItem.addActionListener(this); diag.jpm.add(menuItem); menuItem = new JMenuItem("Assign Subnet Diagram (.drw)"); menuItem.addActionListener(this); diag.jpm.add(menuItem); diag.jpm.addSeparator(); if (isSubnet) { menuItem = new JMenuItem("Display Subnet"); menuItem.addActionListener(this); diag.jpm.add(menuItem); } else { menuItem = new JMenuItem("Choose Source Code"); menuItem.addActionListener(this); diag.jpm.add(menuItem); menuItem = new JMenuItem("Display Source Code"); menuItem.addActionListener(this); diag.jpm.add(menuItem); } diag.jpm.addSeparator(); menuItem = new JMenuItem("Toggle Multiplexing"); menuItem.addActionListener(this); diag.jpm.add(menuItem); menuItem = new JMenuItem("Set Multiplexing Factor"); menuItem.addActionListener(this); diag.jpm.add(menuItem); menuItem = new JMenuItem("Clear Multiplexing Factor"); menuItem.addActionListener(this); diag.jpm.add(menuItem); diag.jpm.addSeparator(); JMenuItem menuItem1 = new JMenuItem( "Choose Component/Subnet Class"); menuItem1.addActionListener(this); diag.jpm.add(menuItem1); JMenuItem menuItem2 = new JMenuItem("Display Full Class Name"); menuItem2.addActionListener(this); diag.jpm.add(menuItem2); JMenuItem menuItem3 = new JMenuItem("Display Description and Port Info"); menuItem3.addActionListener(this); diag.jpm.add(menuItem3); if (diag.diagLang == null) { menuItem1.setEnabled(false); } if (diag.diagLang.label.equals("JSON")){ menuItem1.setEnabled(false); menuItem2.setEnabled(false); } if (!(diag.diagLang.label.equals("Java"))){ menuItem3.setEnabled(false); } diag.jpm.addSeparator(); menuItem = new JMenuItem( "Clear Associated Diagram and/or Class"); menuItem.addActionListener(this); diag.jpm.add(menuItem); } } else { menuItem = new JMenuItem("Edit Item"); menuItem.addActionListener(this); diag.jpm.add(menuItem); if (type.equals(Block.Types.EXTPORT_IN_BLOCK) || type.equals(Block.Types.EXTPORT_OUT_BLOCK)) { diag.jpm.addSeparator(); menuItem = new JMenuItem( "Toggle Substream Sensitive / Normal"); menuItem.addActionListener(this); diag.jpm.add(menuItem); } } diag.jpm.addSeparator(); } if (this instanceof Enclosure) { // menuItem = new JMenuItem("Toggle Colour"); // diag.jpm.add(menuItem); // menuItem.addActionListener(this); } else { menuItem = new JMenuItem("Toggle Visible/Invisible"); diag.jpm.add(menuItem); menuItem.addActionListener(this); } diag.jpm.addSeparator(); menuItem = new JMenuItem("Delete"); diag.jpm.add(menuItem); menuItem.addActionListener(this); } public void actionPerformed(ActionEvent e) { String s = e.getActionCommand(); diag.jpm = null; if (s.equals("Edit Process Name or Description") || s.equals("Edit Description")) { editDescription(DrawFBP.MODIFY); diag.changed = true; return; } if (s.equals("Edit Item")) { // one-line descriptions String ans = (String) MyOptionPane.showInputDialog(driver.frame, "Enter or change text", "Edit Item", MyOptionPane.PLAIN_MESSAGE, null, null, description); if (ans != null/* && ans.length() > 0*/) { description = ans.trim(); diag.changed = true; if (this instanceof IIPBlock) { IIPBlock ib = (IIPBlock) this; description = ib.checkNestedChars(description); //height = driver.gFontHeight + 6; FontMetrics metrics = driver.osg.getFontMetrics(driver.fontf); String t = description; if (t.length() == 1) t = " " + t + " "; byte[] str = t.getBytes(); width = metrics.bytesWidth(str, 0, t.length()); for (Arrow arrow : diag.arrows.values()) { if (arrow.fromId == id && arrow.fromY == arrow.toY) // i.e. // horizontal arrow.fromX = cx + width / 2; } calcEdges(); } } driver.frame.update(driver.osg); diag.changed = true; return; } if (s.startsWith("Toggle Subnet On/Off")) { isSubnet = !isSubnet; diag.changed = true; return; } if (s.startsWith("Assign Subnet Diagram")) { assignSubnetDiagram(); if (isSubnet) codeFileName = null; //isSubnet = true; return; } if (s.equals("Choose Source Code")) { selectSourceCode(); diag.changed = true; return; } if (s.equals("Display Source Code")) { if (isSubnet) return; if (codeFileName == null) { MyOptionPane.showMessageDialog(driver.frame, "No code associated with block", MyOptionPane.WARNING_MESSAGE); return; } showCode(); return; } if (s.equals("Choose Component/Subnet Class")) { if (codeFileName != null) { if (!(codeFileName.toLowerCase().endsWith(".java"))) { if (MyOptionPane.YES_OPTION != MyOptionPane .showConfirmDialog( driver.frame, "Non-Java source is associated with block - if you choose a Java class, you will lose this - go ahead?", "Previous non-Java source", MyOptionPane.YES_NO_OPTION)) { return; } codeFileName = null; } } try { selectJavaClass(); } catch (MalformedURLException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } diag.changed = true; return; } if (s.equals("Display Subnet")) { if (diagramFileName == null) { MyOptionPane.showMessageDialog(driver.frame, "Subnet not selected", MyOptionPane.ERROR_MESSAGE); } else { String t = diagramFileName; File file = null; // if (t.startsWith("/") || t.substring(1, 2).equals(":")) file = new File(t); // else // file = new File(DrawFBP.makeAbsFileName(t, // diag.file.getAbsolutePath())); // File f = new File(diagramFileName); driver.openAction(file.getAbsolutePath()); } return; } if (s.equals("Clear Associated Diagram and/or Class")) { codeFileName = null; diagramFileName = null; javaClass = null; fullClassName = null; diag.changed = true; driver.frame.repaint(); inputPortAttrs = null; outputPortAttrs = null; isSubnet = false; diag.changed = true; return; } if (s.equals("Display Full Class Name")) { if (javaClass == null && fullClassName == null) { MyOptionPane.showMessageDialog(driver.frame, "No component code assigned", MyOptionPane.ERROR_MESSAGE); return; } if ((javaClass == null) != (fullClassName == null)) { MyOptionPane.showMessageDialog(driver.frame, "One of class name and full class name is null, but the other isn't:\n" + "class name - " + javaClass + "\n" + "full class name - " + fullClassName, MyOptionPane.ERROR_MESSAGE); return; } if (javaClass != null || fullClassName != null) { MyOptionPane.showMessageDialog(driver.frame, fullClassName); } return; } if (s.equals("Toggle Multiplexing")) { multiplex = !multiplex; if (!multiplex) mpxfactor = null; driver.frame.repaint(); diag.changed = true; return; } if (s.equals("Set Multiplexing Factor")) { String ans = (String) MyOptionPane.showInputDialog(driver.frame, "Enter or change text", "Set Multiplexing Factor", MyOptionPane.PLAIN_MESSAGE, null, null, mpxfactor); if ((ans != null) && (ans.length() > 0)) { mpxfactor = ans; multiplex = true; } diag.changed = true; return; } if (s.equals("Clear Multiplexing Factor")) { mpxfactor = null; diag.changed = true; return; } if (s.equals("Display Description and Port Info")) { if (javaClass == null) { MyOptionPane.showMessageDialog(driver.frame, "No class information associated with block", MyOptionPane.ERROR_MESSAGE); return; } displayPortInfo(); return; } if (this instanceof ExtPortBlock && s.equals("Toggle Substream Sensitive / Normal")) { ExtPortBlock eb = (ExtPortBlock) this; eb.substreamSensitive = !eb.substreamSensitive; driver.frame.repaint(); diag.changed = true; return; } if (s.equals("Edit Subnet Label")) { // Block must be an Enclosure diag.cEncl = (Enclosure) this; String ans = (String) MyOptionPane.showInputDialog(driver.frame, "Enter or change text", "Edit subnet label", MyOptionPane.PLAIN_MESSAGE, null, null, diag.cEncl.description); if (ans != null/* && ans.length() > 0*/) { diag.cEncl.description = ans; } driver.frame.repaint(); diag.changed = true; return; } if (s.equals("Edit Subnet Port Name")) { // Block must be an Enclosure // this sets switch, which next click on arrow will test diag.cEncl = (Enclosure) this; diag.cEncl.editPortName = true; MyOptionPane.showMessageDialog(driver.frame, "Select arrow crossing left or right side"); diag.findArrowCrossing = true; driver.frame.repaint(); diag.changed = true; return; } if (s.equals("Toggle Substream Sensitivity")) { // Block must be an Enclosure // this sets switch, which next click on arrow will test diag.cEncl = (Enclosure) this; diag.cEncl.changeSubstreamSensitivity = !diag.cEncl.changeSubstreamSensitivity; MyOptionPane.showMessageDialog(driver.frame, "Select arrow crossing left or right side"); diag.findArrowCrossing = true; driver.frame.repaint(); diag.changed = true; return; } if (s.startsWith("Drag Contents")) { Enclosure enc = (Enclosure) this; enc.draggingContents = true; diag.findEnclosedBlocksAndArrows(enc); driver.frame.repaint(); diag.changed = true; return; } if (s.equals("Excise Subnet")) { // Block must be an Enclosure String ans = (String) MyOptionPane.showInputDialog(driver.frame, "Enter or change name", "Enter subnet diagram relative file name", MyOptionPane.PLAIN_MESSAGE, null, null, null); if (ans != null/* && ans.length() > 0*/) { ans = ans.trim(); if (!(ans.toLowerCase().endsWith(".drw"))) ans += ".drw"; } else return; //-------------------- Block b = diag.excise((Enclosure) this); //-------------------- // from here on driver.curDiag will be the new (subnet) diagram b.description = ans; driver.curDiag.desc= ans; driver.curDiag.title = ans; final boolean NOCHOOSE = false; driver.curDiag.delBlock(this, NOCHOOSE); driver.curDiag.foundBlock = null; driver.frame.repaint(); driver.curDiag.changed = true; return; } if (s.equals("Toggle Visible/Invisible")) { visible = !visible; diag.changed = true; driver.frame.repaint(); return; } if (s.equals("Toggle Colour")) { Enclosure enc = (Enclosure) this; enc.coloured = !enc.coloured; diag.changed = true; driver.frame.repaint(); return; } if (s.equals("Delete")) { final boolean CHOOSE = true; diag.delBlock(this, CHOOSE); diag.foundBlock = null; diag.changed = true; // diag.changeCompLang(); driver.frame.repaint(); } // if (s.equals("Exit")) { // diag.foundBlock = null; // driver.frame.repaint(); // } } // Used if not single line block contents boolean editDescription(int option) { final JTextArea area = new JTextArea(4, 3); JScrollPane pane = new JScrollPane(area); area.setText(description); area.setFont(driver.fontg); //JScrollPane pane = new JScrollPane(area); // ensure area within frame gets focus area.addHierarchyListener(new HierarchyListener() { public void hierarchyChanged(HierarchyEvent he) { if ((he.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) { //if (area.isShowing()) { SwingUtilities.invokeLater(new Runnable() { public void run() { area.requestFocusInWindow(); } }); //} } } }); String t = ""; for (int i = 0; i < driver.blockTypes.length; i++) { if (driver.blockTypes[i].equals(type)) { t = driver.blockNames[i]; break; } } String init = (option < DrawFBP.MODIFY) ? "Create " : "Modify "; int result = MyOptionPane.showOptionDialog(driver.frame, new Object[]{ "Enter/change name or description", pane}, init + t); //if (option > DrawFBP.EDIT_NO_CANCEL) { if (result != MyOptionPane.OK_OPTION) return false; //} description = area.getText(); diag.changed = true; driver.frame.repaint(); return true; } void assignSubnetDiagram() { if (diagramFileName != null) { if (MyOptionPane.YES_OPTION != MyOptionPane.showConfirmDialog( driver.frame, "Block already associated with diagram (" + diagramFileName + ") - change it?", "Change diagram", MyOptionPane.YES_NO_OPTION)) { return; } diagramFileName = null; } String t = driver.properties.get("currentDiagramDir"); if (t == null) t = System.getProperty("user.home"); MyFileChooser fc = new MyFileChooser(new File(t), diag.fCPArr[DrawFBP.DIAGRAM]); int returnVal = fc.showOpenDialog(); String dFN = null; if (returnVal == MyFileChooser.APPROVE_OPTION) { dFN = driver.getSelFile(fc); String suff = diag.fCPArr[DrawFBP.DIAGRAM].fileExt; if (!(dFN.endsWith(suff))) dFN += suff; driver.curDiag.changed = true; File df = driver.openAction(dFN); if (df == null) return; /* int i = diag.diagramIsOpen(df.getAbsolutePath()); if (i > -1 ){ ButtonTabComponent b = (ButtonTabComponent) driver.jtp .getTabComponentAt(i); driver.curDiag = b.diag; //curDiag.tabNum = i; driver.jtp.setSelectedIndex(i); driver.frame.repaint(); return; } */ //driver.getNewDiag(); diagramFileName = dFN; diag = driver.curDiag; isSubnet = true; if (df.exists()) { //int res = MyOptionPane.showConfirmDialog(driver.frame, // "File already exists - erase contents?", // "Erase contents?", MyOptionPane.YES_NO_OPTION); //if (res != MyOptionPane.YES_OPTION) return; //Set<Integer> set = diag.arrows.keySet(); //for (Integer i : set) { // diag.arrows.remove(i); //} //set = diag.blocks.keySet(); //for (Integer i : set) { // diag.blocks.remove(i); //} } diag.diagFile = df; diag.desc = df.getName(); diag.title = df.getName(); driver.jtp.setSelectedIndex(diag.tabNum); MyOptionPane.showMessageDialog(driver.frame, "New subnet: fill in names for Ext Ports In and Out", MyOptionPane.INFORMATION_MESSAGE); diag.xa = driver.frame.getWidth() / 2 - 300; diag.ya = driver.frame.getHeight() / 2; driver.createBlock(Block.Types.EXTPORT_IN_BLOCK); diag.xa = driver.frame.getWidth() / 2 + 100; diag.ya = driver.frame.getHeight() / 2; driver.createBlock(Block.Types.EXTPORT_OUT_BLOCK); /* } else { int i = diag.diagramIsOpen(f.getAbsolutePath()); if (i > -1 ){ ButtonTabComponent b = (ButtonTabComponent) driver.jtp .getTabComponentAt(i); driver.curDiag = b.diag; //curDiag.tabNum = i; driver.jtp.setSelectedIndex(i); driver.frame.repaint(); return; } res = MyOptionPane.showConfirmDialog(driver.frame, "File already exists - erase contents?", "Erase contents?", MyOptionPane.YES_NO_CANCEL_OPTION); if (res == MyOptionPane.CANCEL_OPTION) return; if (res == MyOptionPane.NO_OPTION) { df = driver.openAction(dFN); if (df == null) return; diagramFileName = dFN; diag = driver.curDiag; isSubnet = true; diag.diagFile = df; diag.desc = ans; diag.title = ans; driver.jtp.setSelectedIndex(diag.tabNum); } else { f.delete(); MyOptionPane.showMessageDialog(driver.frame, "Starting new subnet: " + f.getName(), MyOptionPane.INFORMATION_MESSAGE); df = driver.openAction(dFN); if (df == null) return; diagramFileName = dFN; diag = driver.curDiag; isSubnet = true; diag.diagFile = df; diag.desc = ans; diag.title = ans; driver.jtp.setSelectedIndex(diag.tabNum); MyOptionPane.showMessageDialog(driver.frame, "Fill in names for Ext Ports In and Out", MyOptionPane.INFORMATION_MESSAGE); diag.xa = driver.frame.getWidth() / 2 - 300; diag.ya = driver.frame.getHeight() / 2; driver.createBlock(Block.Types.EXTPORT_IN_BLOCK); diag.xa = driver.frame.getWidth() / 2 + 100; diag.ya = driver.frame.getHeight() / 2; driver.createBlock(Block.Types.EXTPORT_OUT_BLOCK); */ } diag.parent = this; diag.changed = true; driver.frame.repaint(); } void selectJavaClass() throws MalformedURLException { String oldFullClassName = fullClassName; if (javaClass != null) { if (MyOptionPane.YES_OPTION != MyOptionPane.showConfirmDialog( driver.frame, "Block already associated with class (" + javaClass.getName() + ") - change it?", "Change class", MyOptionPane.YES_NO_OPTION)) { return; } // javaClass = null; // fullClassName = null; } if (!driver.getJavaFBPJarFile()) { MyOptionPane.showMessageDialog(driver.frame, "JavaFBP jar file not specified or found", MyOptionPane.ERROR_MESSAGE); return; } String t = driver.properties.get("currentClassDir"); if (t == null) t = System.getProperty("user.home"); MyFileChooser fc = new MyFileChooser(new File(t), diag.fCPArr[DrawFBP.CLASS]); int returnVal = fc.showOpenDialog(); boolean injar = true; File cFile = null; if (returnVal == MyFileChooser.APPROVE_OPTION) { String res = driver.getSelFile(fc); int i = res.indexOf("!"); if (i > -1) { // looking in a jar file (?) String res2 = res.substring(i + 2); // ! will be followed by // slash res2 = res2.replace('/', '.'); File f = new File(res.substring(0, i)); res = res.substring(0, i) + "!" + res2; URL[] urls = buildUrls(f); if (urls == null) javaClass = null; else { // Create a new class loader with the directory classLoader = new URLClassLoader(urls); try { javaClass = classLoader.loadClass(res2); } catch (ClassNotFoundException e2) { javaClass = null; } catch (NoClassDefFoundError e2) { javaClass = null; } javaClass = getSelectedClass(res.substring(0, i), res2, injar); fullClassName = res; } } else { // we are looking in local class hierarchy (not a jar file) String fs = res; if (fs.endsWith("jar")) cFile = new File(driver.javaFBPJarFile); // ???? else { cFile = new File(fs); if (cFile == null || !(cFile.exists())) { MyOptionPane.showMessageDialog(driver.frame, "Unable to find file " + cFile.getName(), MyOptionPane.ERROR_MESSAGE); return; } } boolean classFound; File fp = null; String u = cFile.getName(); i = u.lastIndexOf(".class"); if (i > -1) u = u.substring(0, i); String error = ""; while (true) { fp = cFile.getParentFile(); if (fp == null) break; //try { classFound = true; URL[] urls = buildUrls(fp); if (urls == null) javaClass = null; else { // Create a new class loader with the directory classLoader = new URLClassLoader(urls); try { javaClass = classLoader.loadClass(u); } catch (ClassNotFoundException e2) { classFound = false; error = "ClassNotFoundException"; } catch (NoClassDefFoundError e2) { classFound = false; error = "NoClassDefFoundError"; } if (classFound) break; String v = fp.getName(); u = v + "." + u; cFile = fp; } //} finally { //} } if (javaClass == null) { MyOptionPane.showMessageDialog(driver.frame, "Class '" + driver.getSelFile(fc) + "' not found (" + error + ")", MyOptionPane.ERROR_MESSAGE); } else { driver.properties.put("currentClassDir", fp.getAbsolutePath()); driver.propertiesChanged = true; fullClassName = fp.getAbsolutePath() + "!" + javaClass.getName(); javaClass = getSelectedClass(fp.getAbsolutePath(), javaClass.getName(), !injar); } } } if (javaClass == null) { MyOptionPane.showMessageDialog(driver.frame, "No class selected", MyOptionPane.ERROR_MESSAGE); } else { if (!fullClassName.equals(oldFullClassName)) displayPortInfo(); diag.changed = true; // diag.changeCompLang(); } return; } URL[] buildUrls(File f) { LinkedList<URL> ll = new LinkedList<URL>(); URL[] urls = null; try { ll.add(f.toURI().toURL()); String curClsDir = driver.properties.get("currentClassDir") + File.separator; if (null != curClsDir) { f = new File(curClsDir); ll.add(f.toURI().toURL()); } f = new File(driver.javaFBPJarFile); ll.add(f.toURI().toURL()); for (String jfv : driver.jarFiles.values()) { f = new File(jfv); ll.add(f.toURI().toURL()); } urls = ll.toArray(new URL[ll.size()]); } catch (MalformedURLException e) { MyOptionPane.showMessageDialog(driver.frame, "Malformed URL: " + fullClassName, MyOptionPane.ERROR_MESSAGE); // e.printStackTrace(); // javaClass = null; urls = null; e.printStackTrace(); } return urls; } void selectSourceCode() { GenLang gl = driver.curDiag.diagLang; if (codeFileName != null) { if (MyOptionPane.YES_OPTION != MyOptionPane.showConfirmDialog(driver.frame, "Block already associated with source code (" + codeFileName + ") - change it?", "Change source code", MyOptionPane.YES_NO_OPTION)) return; } if (!(gl.label.equals("Java")) && javaClass != null) { if (MyOptionPane.NO_OPTION == MyOptionPane.showConfirmDialog( driver.frame, "You have selected a non-Java language and there is a Java class associated with this block - go ahead?", "Java previously used", MyOptionPane.YES_NO_OPTION)) { javaClass = null; codeFileName = null; return; } } String ans = (String) MyOptionPane.showInputDialog(driver.frame, "Edit arbitrary string or browse (enter # to browse)", "Enter/change source code name", MyOptionPane.PLAIN_MESSAGE, null, null, codeFileName); if (ans != null/* && ans.length() > 0*/) { codeFileName = ans.trim(); // javaClass = null; diag.changed = true; } if (codeFileName.equals("#")) { String t = driver.properties.get(gl.srcDirProp); if (t == null) t = System.getProperty("user.home"); MyFileChooser fc = new MyFileChooser(new File(t), diag.fCPArr[DrawFBP.PROCESS]); int returnVal = fc.showOpenDialog(); File cFile = null; if (returnVal == MyFileChooser.APPROVE_OPTION) { cFile = new File(driver.getSelFile(fc)); if (cFile == null || !(cFile.exists())) { if (MyOptionPane.NO_OPTION == MyOptionPane.showConfirmDialog( driver.frame, "You have entered a file name that does not exist - go ahead?", "File does not exist", MyOptionPane.YES_NO_OPTION)) { return; } codeFileName = driver.getSelFile(fc); } else { codeFileName = cFile.getAbsolutePath(); driver.properties.put(gl.srcDirProp, cFile.getParentFile().getAbsolutePath()); driver.propertiesChanged = true; } } } } void showCode() { if (codeFileName == null) { MyOptionPane.showMessageDialog(driver.frame, "No code associated with block", MyOptionPane.ERROR_MESSAGE); return; } String t = codeFileName; // int k = t.lastIndexOf("."); // String suff = t.substring(k + 1); // diag.changeCompLang(); CodeManager cm = new CodeManager(diag); cm.display(new File(t), diag.diagLang); } }