CS 151 - Day 17

Cover page image

Cay S. Horstmann

Lab

lab

Drawing Circles

  1. In the lab17 directory, make three files
  2. Load graphed.html in your web browser (Chrome or Firefox). What happens?
  3. Why?

The JavaScript Console

  1. Introduce a typo into graphed.js (e.g. misspell grahp somewhere). Reload the page. What happens?
  2. Open the browser dev tools (Ctrl+Shift+I on Linux). Select the Console tab. What do you see?
  3. Fix the bug and refresh. What is in the console now?

The Debugger

  1. With the development tools still open, reintroduce the same bug that you just fixed. Now refresh the page. What happens?
  2. You just discovered the debugger. Fix the bug again and now set a breakpoint into the draw method of the Graph “class”. Refresh the page. What happens?
  3. Step inside the draw function of the node. How did you do that?

Inspecting Elements

  1. In the browser, right-click on one of the circles and select Inspect Element. What happens?
  2. What are all the elements in the DOM tree between the root and the circle that you just clicked on?

Selecting

  1. Look at oodp3code/ch08/graphed2/GraphPanel.java. It has a mouse listener for selecting nodes. We want to implement this in JavaScript.
  2. Add a function
    function drawGrabber(x, y) {
      const size = 5;
    
      ...
    }
    
    to the top of graphed.js. Draw a single black rectangle with center (x, y). Follow the draw method of a circle node. Test your method by adding the following to the end of the DOMContentLoaded listener:
          const bounds = n1.getBounds()
          drawGrabber(bounds.x, bounds.y)
          drawGrabber(bounds.x + bounds.width, bounds.y)
          drawGrabber(bounds.x, bounds.y + bounds.height)      
          drawGrabber(bounds.x + bounds.width, bounds.y + bounds.height)
    Remove those test lines when you are done.
  3. Add an event listener into the DOMContentLoaded listener:
      function mouseLocation(event) {
        const rect = panel.getBoundingClientRect();
        return {
          x: event.clientX - rect.left,
          y: event.clientY - rect.top,
        }
      }
    
      const panel = document.getElementById('graphpanel')
      panel.addEventListener('mousedown', event => {
        let mousePoint = mouseLocation(event)
        let selected = ...
        if (...) {
          const bounds = selected.getBounds()
          drawGrabber(bounds.x, bounds.y)
          drawGrabber(bounds.x + bounds.width, bounds.y)
          drawGrabber(bounds.x, bounds.y + bounds.height)      
          drawGrabber(bounds.x + bounds.width, bounds.y + bounds.height)
        }
      })
    
    Fill in the missing parts, looking at GraphPanel.java. What happens when you click on a node? On both nodes?
  4. We can't keep adding SVG elements to the panel. Put this function at a good spot (where the necessary variables are in scope) and call it in both event handlers:
      function repaint() {
        panel.innerHTML = ''
        graph.draw()
        if (selected !== undefined) {
          const bounds = selected.getBounds()
          drawGrabber(bounds.x, bounds.y)
          drawGrabber(bounds.x + bounds.width, bounds.y)
          drawGrabber(bounds.x, bounds.y + bounds.height)      
          drawGrabber(bounds.x + bounds.width, bounds.y + bounds.height)
        }    
      }
    
    Now you should be able to select one or the other node, or deselect both.

Moving a Node

  1. Add a mousemove listener. In JavaScript, there are no separate methods for mouse moving and dragging. To tell that it was a drag, set a variable dragStartPoint in mousedown, set it to undefined in mouseup, and check it in mousemove. If it was set, the mouse is being dragged.
  2. Like in mousedown, you need to transform the event coordinates.
  3. Now do the exact same thing in mousemove that GraphPanel.java does.