/* PseudoCode Interpreted Language (PCIL): Part of the algoviz@vt collection of algorithm visualizations. Copyright (C) 2008 Brandon Malone, Frank Hadlock This file is part of the PseudoCode Interpreted Language. PseudoCode Interpreted Language is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. PseudoCode Interpreted Language is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with PseudoCode Interpreted Language. If not, see . */ /* * GraphInput.java * * Created on March 7, 2008, 2:26 PM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package dynamicmvc; import java.awt.BorderLayout; import java.awt.Dimension; import javax.swing.JCheckBox; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingConstants; /** * * @author Brandon */ public class GraphInput extends JPanel { PrimitivePointer g; boolean isReadOnly; PrimitivePointer v; PrimitivePointer pressed; int lastX; int lastY; GraphPanel graphPanel; JCheckBox cbSetWeights; private PrimitiveList getVertexList() { return (PrimitiveList)((PrimitiveGraph)g.dereference()).getVertices().dereference(); } public PrimitivePointer findVertex(java.awt.event.MouseEvent evt) { for(PrimitivePointer p : getVertexList().getList()) { PrimitiveVertex v = (PrimitiveVertex)p.dereference(); if (v.contains(evt.getX(), evt.getY())) { return p; } } return null; } /** Creates a new instance of GraphInput */ public GraphInput(PrimitivePointer g, int width, int height, boolean isReadOnly) { super(); this.setPreferredSize(new Dimension(width, height)); this.setLayout(new BorderLayout()); this.g = g; this.isReadOnly = isReadOnly; cbSetWeights = new JCheckBox(); cbSetWeights.setText("Manually set graph weights:"); cbSetWeights.setHorizontalTextPosition(SwingConstants.LEADING); add(cbSetWeights, BorderLayout.NORTH); graphPanel = new GraphPanel(this.g); add(graphPanel, BorderLayout.CENTER); if (!isReadOnly) { graphPanel.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { graphClicked(evt); } public void mousePressed(java.awt.event.MouseEvent evt) { graphPressed(evt); } public void mouseReleased(java.awt.event.MouseEvent evt) { graphReleased(evt); } }); graphPanel.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() { public void mouseDragged(java.awt.event.MouseEvent evt) { graphDragged(evt); } }); } } public void graphClicked(java.awt.event.MouseEvent evt) { if (evt.getButton() == java.awt.event.MouseEvent.BUTTON1) { graphLeftButtonClicked(evt); } else { graphRightButtonClicked(evt); } } protected void graphRightButtonClicked(java.awt.event.MouseEvent evt) { PrimitivePointer p = findVertex(evt); if (p != null) { PrimitiveGraph g = (PrimitiveGraph)this.g.dereference(); try { g.deleteVertex(p); repaint(); } catch (DynamicMVCException ex) { ex.printStackTrace(); } } } protected void graphLeftButtonClicked(java.awt.event.MouseEvent evt) { PrimitivePointer p = findVertex(evt); if (p != null) { PrimitiveVertex v = (PrimitiveVertex)p.dereference(); if (this.v == null) { this.v = p; graphPanel.v = this.v; this.repaint(); return; } else { addEdge(p); return; } } String nextName = getNextName(); PrimitivePointer name = PrimitiveFactory.create(PrimitiveString.pseudocodeTypeName(), nextName); PrimitivePointer x = PrimitiveFactory.create(PrimitiveInteger.pseudocodeTypeName(), "x"); PrimitivePointer y = PrimitiveFactory.create(PrimitiveInteger.pseudocodeTypeName(), "y"); PrimitiveInteger iX = (PrimitiveInteger)x.dereference(); PrimitiveInteger iY = (PrimitiveInteger)y.dereference(); ((PrimitiveString)name.dereference()).setValue(nextName); iX.setValue(evt.getX()); iY.setValue(evt.getY()); try { ((PrimitiveGraph)g.dereference()).addVertex(name, x, y); } catch (DynamicMVCException ex) { ex.printStackTrace(); } this.repaint(); } public void graphPressed(java.awt.event.MouseEvent evt) { PrimitivePointer p = findVertex(evt); if (p != null) { this.pressed = p; lastX = evt.getX(); lastY = evt.getY(); } } public void graphReleased(java.awt.event.MouseEvent evt) { this.pressed = null; } public void graphDragged(java.awt.event.MouseEvent evt) { if (pressed == null) { return; } PrimitiveVertex v = (PrimitiveVertex)pressed.dereference(); PrimitiveInteger x = (PrimitiveInteger)v.getX().dereference(); PrimitiveInteger y = (PrimitiveInteger)v.getY().dereference(); int dx = evt.getX() - lastX; int dy = evt.getY() - lastY; lastX = evt.getX(); lastY = evt.getY(); int newX = x.getValue() + dx; int newY = y.getValue() + dy; x.setValue(newX); y.setValue(newY); repaint(); } protected void addEdge(PrimitivePointer p) { if (this.cbSetWeights.isSelected()) { while (true) { // Infinite loop must contain a break String edgeWeight = JOptionPane.showInputDialog(null, "Please enter the edge weight."); if (edgeWeight == null) { return; } try { int n = Integer.parseInt(edgeWeight); PrimitivePointer distance = PrimitiveFactory.create(PrimitiveInteger.pseudocodeTypeName(), "distance"); PrimitiveInteger d = (PrimitiveInteger)distance.dereference(); d.setValue(n); ((PrimitiveGraph)g.dereference()).addEdge(this.v, p, distance); break; } catch (Exception e) { continue; } } } else { ((PrimitiveGraph)g.dereference()).addEdge(this.v, p); } this.v = null; graphPanel.v = null; this.repaint(); } private static String currentName; public static void resetNames() { currentName = null; } private static String getNextName() { if (currentName == null) { currentName = "A"; return currentName; } // what is the length of the current name? int length = currentName.length(); // is the last character a z? char lastChar = currentName.charAt(length - 1); if (lastChar == 'Z') { StringBuilder sb = new StringBuilder(); // make the string one longer, and reset everything to A for(int i = 0; i<=length; i++) { sb.append('A'); } currentName = sb.toString(); } else { // just increment this character lastChar++; String lc = String.valueOf(lastChar); if (length > 1) { currentName = currentName.substring(0, length-2).concat(lc); } else { currentName = lc; } } return currentName; } }