/// Pass user's interaction with list to appropriate handler
    public void valueChanged(ListSelectionEvent e) {
      if (e.getSource() == sourceList) {
        if (!e.getValueIsAdjusting()) {
          int indexS = sourceList.getSelectedIndex();
          srcID = indexS + 1;
          drawTest.repaint();
        }
      }

      if (e.getSource() == destList) {
        if (!e.getValueIsAdjusting()) {
          int indexD = destList.getSelectedIndex();
          dstID = indexD + 17;
          drawTest.repaint();
        }
      }

      if (e.getSource() == routerList) {
        if (!e.getValueIsAdjusting()) {
          indexR = routerList.getSelectedIndex();

          Router temp = statMux.getRouter(indexR);
          int[] pList = temp.getPriorityList();
          audioVal.setText(String.valueOf(pList[0]));
          videoVal.setText(String.valueOf(pList[1]));
          textVal.setText(String.valueOf(pList[2]));
        }
      }

      if (e.getSource() == packTypeList) {
        if (!e.getValueIsAdjusting()) {
          int temp = packTypeList.getSelectedIndex();
          if (temp == 0) {
            type = PacketType.AUDIO;
          } else if (temp == 1) {
            type = PacketType.VIDEO;
          } else {
            type = PacketType.TEXT;
          }
          drawTest.repaint();
        }
      }
    }
  // getDelay function
  // It takes in an optimized path and packet type as input.
  // Based on input, the function calculates delay occured when traveling
  // through the optimized path
  public double getDelay(int[] opath, PacketType type) {
    double delay = 0;

    for (int i = 1; i < 4; i++) {
      Router temp = statMux.getRouter(opath[i] - 4);
      int flow = temp.getFlowLevel();
      int delayR = temp.getDelay();
      int priority = temp.getPriority(type);
      int thr = temp.getThroughput();
      packThrough[i - 1] = thr;

      if (priority == 1) {
        loss[i - 1] = thr / 10.0;
      }
      if (priority == 2) {
        loss[i - 1] = thr / 5.0;
      }

      delay += numPack / thr + delayR + priority * flow;
    }

    return delay;
  }
    /// Check for button clicking and apply appropriate response
    public void actionPerformed(ActionEvent e) {
      /// For each input, pass it to the correct handler
      /// Priority of router will be updated based on input
      /// Upon user's changes of the priority value, repaint
      /// the display component
      if (e.getSource() == aPlus) {
        Router temp = statMux.getRouter(indexR);
        int[] pList = temp.getPriorityList();
        pList[0] = dataBound(pList[0] + 1);
        temp.setPriorityList(pList);
        audioVal.setText(String.valueOf(pList[0]));
        videoVal.setText(String.valueOf(pList[1]));
        textVal.setText(String.valueOf(pList[2]));
        drawTest.repaint();
      }

      if (e.getSource() == aMinus) {
        Router temp = statMux.getRouter(indexR);
        int[] pList = temp.getPriorityList();
        pList[0] = dataBound(pList[0] - 1);
        temp.setPriorityList(pList);
        audioVal.setText(String.valueOf(pList[0]));
        videoVal.setText(String.valueOf(pList[1]));
        textVal.setText(String.valueOf(pList[2]));
        drawTest.repaint();
      }

      if (e.getSource() == vPlus) {
        Router temp = statMux.getRouter(indexR);
        int[] pList = temp.getPriorityList();
        pList[1] = dataBound(pList[1] + 1);
        temp.setPriorityList(pList);
        audioVal.setText(String.valueOf(pList[0]));
        videoVal.setText(String.valueOf(pList[1]));
        textVal.setText(String.valueOf(pList[2]));
        drawTest.repaint();
      }

      if (e.getSource() == vMinus) {
        Router temp = statMux.getRouter(indexR);
        int[] pList = temp.getPriorityList();
        pList[1] = dataBound(pList[1] - 1);
        temp.setPriorityList(pList);
        audioVal.setText(String.valueOf(pList[0]));
        videoVal.setText(String.valueOf(pList[1]));
        textVal.setText(String.valueOf(pList[2]));
        drawTest.repaint();
      }

      if (e.getSource() == tPlus) {
        Router temp = statMux.getRouter(indexR);
        int[] pList = temp.getPriorityList();
        pList[2] = dataBound(pList[2] + 1);
        temp.setPriorityList(pList);
        audioVal.setText(String.valueOf(pList[0]));
        videoVal.setText(String.valueOf(pList[1]));
        textVal.setText(String.valueOf(pList[2]));
        drawTest.repaint();
      }

      if (e.getSource() == tMinus) {
        Router temp = statMux.getRouter(indexR);
        int[] pList = temp.getPriorityList();
        pList[2] = dataBound(pList[2] - 1);
        temp.setPriorityList(pList);
        audioVal.setText(String.valueOf(pList[0]));
        videoVal.setText(String.valueOf(pList[1]));
        textVal.setText(String.valueOf(pList[2]));
        drawTest.repaint();
      }
    }
    public void paint(Graphics g) {
      path = findOptimizedPath(srcID, dstID, type);

      /// Create the drawing board
      Dimension d = getSize();
      g.setColor(Color.white);
      g.fillRect(1, 1, d.width - 2, d.height - 2);

      g.setColor(Color.black);
      g.drawRect(1, 1, d.width - 2, d.height - 2);
      g.setFont(serifFont);

      /// Draw the whole network, including all routers with
      ///     delay and flow level, sources and destinations.
      int numR = 1;
      int w = 95;
      int h = d.height / 5;
      int pos = -1;

      for (int i = 0; i < 3; i++) {
        g.drawOval(w, h + 100 * i, 40, 40);
        g.drawString("S" + String.valueOf(i + 1), w + 13, h + 100 * i - 5);
      }

      for (int i = 0; i < 3; i++) {
        pos++;
        Router temp = statMux.getRouter(pos);
        g.drawOval(w + 110, h + 100 * i, 40, 40);
        g.drawString("R" + String.valueOf(numR++), w + 123, h + 100 * i - 5);
        g.drawString(
            String.valueOf(temp.getDelay() * temp.getPriority(type) + temp.getFlowLevel()),
            w + 125,
            h + 100 * i + 15);
        g.drawString(String.valueOf(temp.getFlowLevel()), w + 125, h + 100 * i + 35);
      }

      h = d.height / 11;
      for (int i = 0; i < 4; i++) {
        pos++;
        Router temp = statMux.getRouter(pos);
        g.drawOval(w + 210, h + 100 * i, 40, 40);
        g.drawString("R" + String.valueOf(numR++), w + 223, h + 100 * i - 5);
        g.drawString(
            String.valueOf(temp.getDelay() * temp.getPriority(type) + temp.getFlowLevel()),
            w + 225,
            h + 100 * i + 15);
        g.drawString(String.valueOf(temp.getFlowLevel()), w + 225, h + 100 * i + 35);
      }

      h = 20;
      for (int i = 0; i < 6; i++) {
        pos++;
        Router temp = statMux.getRouter(pos);
        g.drawOval(w + 310, h + 80 * i, 40, 40);
        g.drawString("R" + String.valueOf(numR++), w + 320, h + 80 * i - 5);
        g.drawString(
            String.valueOf(temp.getDelay() * temp.getPriority(type) + temp.getFlowLevel()),
            w + 325,
            h + 80 * i + 15);
        g.drawString(String.valueOf(temp.getFlowLevel()), w + 325, h + 80 * i + 35);
      }

      for (int i = 0; i < 4; i++) {
        g.drawOval(w + 410, d.height / 11 + 100 * i, 40, 40);
        g.drawString("D" + String.valueOf(i + 1), w + 423, d.height / 11 + 100 * i - 5);
      }

      g.setColor(Color.black);
      int[][] connection = statMux.getConnections();

      /// Check buffer for connections at each step and draw links at layer1
      for (int i = 0; i < connection[path[0] - 1].length; i++) {
        int temp = connection[path[0] - 1][i] - 3;
        g.drawLine(w + 40, (path[0]) * d.height / 5 + 20, w + 110, temp * d.height / 5 + 20);
      }

      /// Check buffer for connections at each step and draw links at layer2
      for (int i = 0; i < connection[path[1] - 1].length; i++) {
        int temp = connection[path[1] - 1][i] - 7;
        g.drawLine(
            w + 150, (path[1] - 3) * d.height / 5 + 20, w + 210, (d.height / 11) + 100 * temp + 20);
      }

      /// Check buffer for connections at each step and draw links at layer3
      for (int i = 0; i < connection[path[2] - 1].length; i++) {
        int temp = connection[path[2] - 1][i] - 11;
        g.drawLine(w + 250, (d.height / 11) + 100 * (path[2] - 7) + 20, w + 310, 80 * temp + 40);
      }

      /// Draw optimized path for packets traveling between source
      /// and destination
      h = d.height / 5;
      Graphics2D g2 = (Graphics2D) g;
      g2.setStroke(new BasicStroke(2));
      g2.setColor(Color.red);

      g2.drawLine(w + 40, h * (path[0]) + 20, w + 110, h * (path[1] - 3) + 20);
      g2.drawLine(
          w + 150, h * (path[1] - 3) + 20, w + 210, (d.height / 11) + 100 * (path[2] - 7) + 20);
      g2.drawLine(
          w + 250, (d.height / 11) + 100 * (path[2] - 7) + 20, w + 310, 80 * (path[3] - 11) + 40);
      g2.drawLine(
          w + 350, 80 * (path[3] - 11) + 40, w + 410, (d.height / 11) + 100 * (path[4] - 17) + 20);

      /// Calculate and display loss, delay, and throughput
      delayTime = getDelay(path, type);
      throughPut = getThroughput(path);

      int numPackLost = getLossRate(numTransfer);

      lossRate = numPackLost / 100000.0 + 0.0005 * delayTime;
      delayVal.setText(String.format("%.2f", delayTime));
      throuVal.setText(String.valueOf(throughPut));
      lossVal.setText(String.format("%.4f", lossRate));
    }