Trouble pushing a box with another box, collision detection

Okay, I think I figured it out. It’s amazing how this even eliminates the need to use any logic to make sure tiles are being moved in a valid way. Amazing to me anyway.

import shiffman.box2d.*;
import org.jbox2d.common.*;
import org.jbox2d.dynamics.joints.*;
import org.jbox2d.collision.shapes.*;
import org.jbox2d.dynamics.*;

Box2DProcessing box2d;
ArrayList boundaries;
Box[][] tiles;
Box box;
Spring spring;
Surface surface;
void setup() {
  size(321, 321);
  box2d = new Box2DProcessing(this);
  box2d.createWorld();
  box2d.setGravity(0, 0);
  addBoundaries();
  surface = new Surface(width/2, height/2);
  tiles = new Box[3][3];
  initTiles();
  bindTilesToSurface();
  spring = new Spring();
}
void draw() {
  background(255);
  box2d.step();
  surface.display();
  spring.update(mouseX, mouseY);
  displayWalls();
  displayTiles();
  //spring.display();
}
void mousePressed() {
  int n = 0;
  for (int c = 0; c < tiles.length; c++) {
    for (int r = 0; r < tiles[0].length && n < 8; r++) {
      if (tiles[c][r].contains(mouseX, mouseY)) {
        spring.bind(mouseX, mouseY, tiles[c][r]);
      }
      n++;
    }
  }
}
void mouseReleased() {
  spring.destroy();
}
void displayWalls() {
  for (int i = 0; i < boundaries.size(); i++) {
    Boundary wall = (Boundary) boundaries.get(i);
    wall.display();
  }
}
void displayTiles() {
  int n = 0;
  for (int c = 0; c < tiles.length; c++) {
    for (int r = 0; r < tiles[0].length && n < 8; r++) {
      tiles[c][r].display();
      n++;
    }
  }
}
void addBoundaries() {
  boundaries = new ArrayList();
  boundaries.add(new Boundary(width/2, height-5, width, 10, 0));
  boundaries.add(new Boundary(width/2, 5, width, 10, 0));
  boundaries.add(new Boundary(width-5, height/2, 10, height, 0));
  boundaries.add(new Boundary(5, height/2, 10, height, 0));
}
void initTiles() {
  int n = 0;
  for (int c = 0; c < tiles.length; c++) {
    for (int r = 0; r < tiles[0].length && n < 8; r++) {
      tiles[c][r] = new Box(50 + 100 * c, 50 + 100 * r);
      n++;
    }
  }
}
void bindTilesToSurface() {
  int n = 0;
  for (int c = 0; c < tiles.length; c++) {
    for (int r = 0; r < tiles[0].length && n < 8; r++) {
      tiles[c][r].bind(surface);
      n++;
    }
  }
}
class Boundary {
  float x, y, w, h;
  Body b;
  Boundary(float x, float y, float w, float h, float a) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    PolygonShape ps = new PolygonShape();
    float box2dW = box2d.scalarPixelsToWorld(w/2);
    float box2dH = box2d.scalarPixelsToWorld(h/2);
    ps.setAsBox(box2dW, box2dH);
    BodyDef bd = new BodyDef();
    bd.type = BodyType.STATIC;
    bd.angle = a;
    bd.position.set(box2d.coordPixelsToWorld(x, y));
    b = box2d.createBody(bd);
    b.createFixture(ps, 1);
  }
  void display() {
    fill(75);
    noStroke();
    rectMode(CENTER);
    float a = b.getAngle();
    pushMatrix();
    translate(x, y);
    rotate(-a);
    rect(0, 0, w, h);
    popMatrix();
  }
}
class Box {
  FrictionJoint frictionJoint;
  Body body;
  float x, y;
  float w, h;
  Box(float x, float y) {
    this.x = x;
    this.y = y;
    w = 100;
    h = 100;
    makeBody(new Vec2(x, y));
  }
  boolean contains(float x, float y) {
    Vec2 worldPoint = box2d.coordPixelsToWorld(x, y);
    Fixture f = body.getFixtureList();
    boolean inside = f.testPoint(worldPoint);
    return inside;
  }
  void makeBody(Vec2 center) {
    BodyDef bd = new BodyDef();
    bd.type = BodyType.DYNAMIC;
    bd.position.set(box2d.coordPixelsToWorld(center));
    bd.fixedRotation = true;
    body = box2d.createBody(bd);

    PolygonShape ps = new PolygonShape();
    Vec2[] vertices = new Vec2[8];
    vertices[0] = box2d.vectorPixelsToWorld(new Vec2(-50, -48));
    vertices[1] = box2d.vectorPixelsToWorld(new Vec2(-50, 48));
    vertices[2] = box2d.vectorPixelsToWorld(new Vec2(-48, 50));
    vertices[3] = box2d.vectorPixelsToWorld(new Vec2(48, 50));
    vertices[4] = box2d.vectorPixelsToWorld(new Vec2(50, 48));
    vertices[5] = box2d.vectorPixelsToWorld(new Vec2(50, -48));
    vertices[6] = box2d.vectorPixelsToWorld(new Vec2(48, -50));
    vertices[7] = box2d.vectorPixelsToWorld(new Vec2(-48, -50));
    ps.set(vertices, vertices.length);

    FixtureDef fd = new FixtureDef();
    fd.shape = ps;
    fd.density = 1;
    fd.friction = 0;
    fd.restitution = 0.0;
    body.createFixture(fd);
  }
  void display() {
    Vec2 pos = box2d.getBodyPixelCoord(body);
    float a = body.getAngle();
    pushMatrix();
    translate(pos.x, pos.y);
    rotate(-a);
    fill(255, 255, 240);
    stroke(125, 125, 110);
    strokeWeight(2);
    rectMode(CENTER);
    rect(0, 0, w, h, 5);
    popMatrix();
  }
  void killBody() {
    box2d.destroyBody(body);
  }
  void bind(Surface surface) {
    FrictionJointDef fj = new FrictionJointDef();
    fj.bodyA = body;
    fj.bodyB = surface.body;
    fj.maxForce = 1000;
    fj.maxTorque = 0;
    fj.collideConnected = false;
    frictionJoint = (FrictionJoint) box2d.world.createJoint(fj);
  }
}
class Spring {
  MouseJoint mouseJoint;
  Spring() {
    mouseJoint = null;
  }
  void update(float x, float y) {
    if (mouseJoint != null) {
      Vec2 mouseWorld = box2d.coordPixelsToWorld(x, y);
      mouseJoint.setTarget(mouseWorld);
    }
  }
  void display() {
    if (mouseJoint != null) {
      Vec2 v1 = new Vec2(0, 0);
      mouseJoint.getAnchorA(v1);
      Vec2 v2 = new Vec2(0, 0);
      mouseJoint.getAnchorB(v2);

      v1 = box2d.coordWorldToPixels(v1);
      v2 = box2d.coordWorldToPixels(v2);
      stroke(0);
      strokeWeight(1);
      line(v1.x, v1.y, v2.x, v2.y);
    }
  }
  void bind(float x, float y, Box box) {
    MouseJointDef md = new MouseJointDef();
    md.bodyA = box2d.getGroundBody();
    md.bodyB = box.body;
    Vec2 mp = box2d.coordPixelsToWorld(x, y);
    md.target.set(mp);
    md.maxForce = 1000.0 * box.body.m_mass;
    md.frequencyHz = 5.0;
    md.dampingRatio = 0.9;
    mouseJoint = (MouseJoint) box2d.world.createJoint(md);
  }
  void destroy() {
    if (mouseJoint != null) {
      box2d.world.destroyJoint(mouseJoint);
      mouseJoint = null;
    }
  }
}
class Surface {
  FrictionJoint frictionJoint;
  Body body;
  float x, y, w, h;
  Surface(float x, float y) {
    this.x = x;
    this.y = y;
    w = width;
    h = height;
    makeBody(new Vec2(x, y), w, h);
  }
  void display() {
    Vec2 pos = box2d.getBodyPixelCoord(body);
    rectMode(CENTER);
    pushMatrix();
    translate(pos.x, pos.y);
    fill(0, 127, 0);
    noStroke();
    rect(0, 0, w, h);
    popMatrix();
  }
  void makeBody(Vec2 center, float w, float h) {
    BodyDef bd = new BodyDef();
    bd.type = BodyType.STATIC;
    bd.position.set(box2d.coordPixelsToWorld(center));
    bd.fixedRotation = true;
    body = box2d.createBody(bd);

    PolygonShape ps = new PolygonShape();
    float box2dW = box2d.scalarPixelsToWorld(w/2);
    float box2dH = box2d.scalarPixelsToWorld(h/2);
    ps.setAsBox(box2dW, box2dH);

    FixtureDef fd = new FixtureDef();
    fd.shape = ps;
    body.createFixture(fd);
  }
}