Answered step by step
Verified Expert Solution
Link Copied!

Question

00
1 Approved Answer

UML class diagram of this program CompilerGUI.java import javax.swing.*; import javax.swing.border.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.*; /** * Purpose: Creates a GUI

UML class diagram of this program

CompilerGUI.java

import javax.swing.*; import javax.swing.border.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.*;

/** * Purpose: Creates a GUI for testing the CompilerGraph and related classes. */ public class CompilerGUI extends JFrame { private static final int TEXT_FIELD_WIDTH = 7; CompilerGraph graph; boolean initialized = false; public CompilerGUI() { super("Class Dependency Graph"); setLocationRelativeTo(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(new BorderLayout(5, 10)); //Initialize JPanels JPanel inputFrame = new JPanel(new BorderLayout(25,0)); inputFrame.setBorder(new EmptyBorder(10, 20, 0, 20)); JPanel outputFrame = new JPanel(new BorderLayout()); JPanel inputLabels = new JPanel(new BorderLayout()); JPanel inputFields = new JPanel(new BorderLayout()); JPanel inputButtons = new JPanel(new BorderLayout(10,5)); //Initialize components //Labels JLabel fileLabel = new JLabel("Input file name: "); JLabel classLabel = new JLabel("Class to recompile: "); //Fields final JTextField fileField = new JTextField(TEXT_FIELD_WIDTH); final JTextField classField = new JTextField(TEXT_FIELD_WIDTH); //Buttons JButton buildButton = new JButton("Build Directed Graph"); JButton topoButton = new JButton("Topological Order"); //Output area JLabel recompileLabel = new JLabel("Recompilation Order: "); final JTextArea outputArea = new JTextArea(11, 50); JScrollPane scrollPane = new JScrollPane(outputArea); outputArea.setEditable(false); //Listeners buildButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { Scanner fileIn = null; String fileName = fileField.getText();

try { fileIn = new Scanner(new BufferedReader( new FileReader(fileName))); graph = new CompilerGraph(); graph.initializeGraph(fileIn); initialized = true; JOptionPane.showMessageDialog(null, "Graph built succesfully!", "Success", JOptionPane.INFORMATION_MESSAGE); } catch (IOException e) { JOptionPane.showMessageDialog(null, "\"" + fileName + "\"" + " is not a valid input. Please enter a valid filename.", "Invalid Input", JOptionPane.ERROR_MESSAGE); } catch (CycleDetectedException e) { JOptionPane.showMessageDialog(null, "A cycle has been" + "detected. Please try a different input.", "Cycle Detected", JOptionPane.ERROR_MESSAGE); }

finally { if (fileIn != null) { fileIn.close(); } } } }); topoButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { if (!initialized) { JOptionPane.showMessageDialog(null, "No graph has been " + "initialized. Please initialize a graph.", "Invalid Graph", JOptionPane.ERROR_MESSAGE); } else { try { outputArea.setText(graph.topologicalOrder( classField.getText())); } catch(InvalidClassNameException exc) { JOptionPane.showMessageDialog(null, exc.getClassName() + " is not a valid class name. Please enter a valid" + " class name.", "Invalid Class Name", JOptionPane.ERROR_MESSAGE); } } } }); //Add components to panels inputLabels.add(fileLabel, BorderLayout.NORTH); inputLabels.add(classLabel, BorderLayout.SOUTH); inputFields.add(fileField, BorderLayout.NORTH); inputFields.add(classField, BorderLayout.SOUTH); inputButtons.add(buildButton, BorderLayout.NORTH); inputButtons.add(topoButton, BorderLayout.SOUTH); inputFrame.add(inputLabels, BorderLayout.WEST); inputFrame.add(inputFields, BorderLayout.CENTER); inputFrame.add(inputButtons, BorderLayout.EAST); outputFrame.add(recompileLabel, BorderLayout.NORTH); outputFrame.add(outputArea, BorderLayout.SOUTH); add(inputFrame, BorderLayout.NORTH); add(outputFrame, BorderLayout.SOUTH); }

public static void main(String[] args) { CompilerGUI gui = new CompilerGUI(); gui.pack(); gui.setVisible(true); } }

CompilerGraph.java

import java.util.*; import java.util.Map.Entry; import java.io.*;

/** * Purpose: Implements the fields and methods necessary to build a directed * * * graph of vertices. */ public class CompilerGraph { private HashMap vertices; private ArrayList> adjacencies; private int curIdx = 0; private HashMap vertexMap = new HashMap<>(); private ArrayList headList; private Stack vertStack = new Stack(); public CompilerGraph() { vertices = new HashMap<>(); vertexMap = new HashMap<>(); adjacencies = new ArrayList<>(); headList = new ArrayList<>(); } // Initializes the graph and builds the agacency list. public void initializeGraph(Scanner input) { Scanner curLine; String curName; Vertex curVertex; while (input.hasNextLine()) { curLine = new Scanner(input.nextLine()); curName = curLine.next(); headList.add(curName); if (vertexMap.containsKey(curName)) { curVertex = vertexMap.get(curName); if (curVertex.isDiscovered()) { throw new CycleDetectedException(curVertex.getValue()); } else { curVertex.setDiscovered(); } } else { vertexMap.put(curName, new Vertex(curName)); } while(curLine.hasNext()) { String newName = curLine.next(); if (vertexMap.containsKey(newName)) { Vertex newVertex = vertexMap.get(newName); vertexMap.get(curName).addChild(newVertex); if (newVertex.isDiscovered()) { throw new CycleDetectedException(newVertex.getValue()); } else { newVertex.setDiscovered(); } } else { vertexMap.put(newName, new Vertex(newName)); vertexMap.get(curName).addChild(vertexMap.get(newName)); } } } int vertIdx = 0; String newName = ""; for (String head : headList) { curVertex = vertexMap.get(head); buildAdjacencyList(curVertex); } } // Takes a single vertex and adds to the adjacency list that // vertex and all of its children, utilizing the addEdge() method public void buildAdjacencyList(Vertex vertex) { String curName = ""; int vertIdx = 0; String newName = ""; curName = vertex.getValue(); if (vertices.containsValue(curName)) { vertIdx = getKey(curName); } else { vertIdx = curIdx; vertices.put(curIdx, curName); curIdx++; adjacencies.add(new LinkedList()); } if (vertex.hasChildren()){ for (Vertex child : vertex.getChildren()) { addEdge(vertex, child); buildAdjacencyList(child); } } } // Adds an edge to the corresponding adjacency list public void addEdge(Vertex source, Vertex destination) { int sourceIdx = getKey(source.getValue()); int destIdx; if (vertices.containsValue(destination.getValue())) { destIdx = getKey(destination.getValue()); } else { destIdx = curIdx; curIdx++; vertices.put(destIdx, destination.getValue()); adjacencies.add(new LinkedList()); } adjacencies.get(sourceIdx).add(destIdx); } // Helper method to simplify getting the corresponding key for a given value // in the vertices HashMap public Integer getKey(String value) { for(Entry entry : vertices.entrySet()) { if (entry.getValue().equals(value)) { return entry.getKey(); } } return -1; } // Returns as a String the topological order emmanating from the given class // name. Throws an Exception if the class name does not exist in the graph. // Initializes the depthFirstSearch() method. public String topologicalOrder(String vertName) { // Resets the discovered and finished flags for each vertex for (Entry entry : vertexMap.entrySet()) { entry.getValue().reset(); } String result = ""; if (vertices.containsValue(vertName)){ depthFirstSearch(vertexMap.get(vertName));

while (!vertStack.isEmpty()) { result += vertStack.pop().getValue() + " "; }

return result; } else { throw new InvalidClassNameException(vertName); } } // Utilizes a depth first search algorithm to generate the topological order // from a given vertex. public void depthFirstSearch(Vertex vertex) { if (vertex.isDiscovered()) { throw new CycleDetectedException(vertex.getValue()); } if (vertex.isFinished()) { return; } vertex.setDiscovered(); if (vertex.hasChildren()) { for (Vertex child : vertex.getChildren()) { depthFirstSearch(child); } } vertex.setFinished(); vertStack.push(vertex); }

}

Vertex.java

import java.util.*; /** * Purpose: Implements the methods and fields necessary to create a class for * * * a vertex in a directed graph/ */ public class Vertex { private ArrayList> children; private T value; private boolean discovered = false; private boolean finished = false; public Vertex(T value) { this.value = value; children = new ArrayList<>(); } public Vertex(T value, ArrayList> children) { this.value = value; this.children = children; } public void addChild(Vertex child) { children.add(child); } public ArrayList> getChildren() { return children; } public T getValue() { return value; } public boolean hasChildren() { return (children.size() > 0); } public boolean isDiscovered() { return discovered; } public boolean isFinished() { return finished; } public void setDiscovered() { discovered = true; } public void setFinished() { finished = true; } // Resets the discovered and finished flags public void reset() { discovered = false; finished = false; }

}

CycleDetectedException.java

/** ** Date: Oct 12, 2016 * Purpose: Implements an Exception for when there is a cycle detected within * * * the inputted graph. */ public class CycleDetectedException extends RuntimeException { private String cycleVert = "";

/** * Creates a new instance of CycleDetectedException without * detail message. */ public CycleDetectedException() { }

/** * Constructs an instance of CycleDetectedException with the * specified detail message. * * @param msg the detail message. */ public CycleDetectedException(String vertName) { cycleVert = vertName; } public String getCycleVertex() { return cycleVert; } }

InvalidClassNameException.java

/* * Purpose: Implements an Exception for when the user inputs the name of a class * * * not found in the graph. The illegalCLass field allows the GUI to pull the * * * offending class name. */ public class InvalidClassNameException extends RuntimeException { private String illegalClass = "";

/** * Creates a new instance of CycleDetectedException without * detail message. */ public InvalidClassNameException() { }

/** * Constructs an instance of CycleDetectedException with the * specified detail message. * * @param msg the detail message. */ public InvalidClassNameException(String className) { illegalClass = className; } public String getClassName() { return illegalClass; } }

test.txt

ClassA ClassC ClassE ClassB ClassD ClassG ClassE ClassB ClassF ClassH ClassI ClassC

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access with AI-Powered Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Students also viewed these Databases questions