private void computeSize(boolean immediate) {
   hidePopup();
   Bounds bounds;
   CircuitState circState = circuitState;
   if (circState == null) {
     bounds = Bounds.create(0, 0, 50, 50);
   } else {
     bounds = circState.getCircuit().getAppearance().getAbsoluteBounds();
   }
   int width = bounds.getX() + bounds.getWidth() + BOUNDS_BUFFER;
   int height = bounds.getY() + bounds.getHeight() + BOUNDS_BUFFER;
   Size dim;
   if (canvasPane == null) {
     dim = new Size(width, height);
   } else {
     dim = canvasPane.supportPreferredSize(width, height);
   }
   if (!immediate) {
     Bounds old = oldPreferredSize;
     if (old != null
         && Math.abs(old.getWidth() - dim.width) < THRESH_SIZE_UPDATE
         && Math.abs(old.getHeight() - dim.height) < THRESH_SIZE_UPDATE) {
       return;
     }
   }
   oldPreferredSize = Bounds.create(0, 0, dim.width, dim.height);
   setPreferredSize(dim);
   revalidate();
 }
  @Override
  public void doAction(Action canvasAction) {
    Circuit circuit = circuitState.getCircuit();
    if (!proj.getLogisimFile().contains(circuit)) {
      return;
    }

    if (canvasAction instanceof ModelReorderAction) {
      int max = getMaxIndex(getModel());
      ModelReorderAction reorder = (ModelReorderAction) canvasAction;
      List<ReorderRequest> rs = reorder.getReorderRequests();
      List<ReorderRequest> mod = new ArrayList<ReorderRequest>(rs.size());
      boolean changed = false;
      boolean movedToMax = false;
      for (ReorderRequest r : rs) {
        CanvasObject o = r.getObject();
        if (o instanceof AppearanceElement) {
          changed = true;
        } else {
          if (r.getToIndex() > max) {
            int from = r.getFromIndex();
            changed = true;
            movedToMax = true;
            if (from == max && !movedToMax) {
              // this change is ineffective - don't add it
            } else {
              mod.add(new ReorderRequest(o, from, max));
            }
          } else {
            if (r.getToIndex() == max) movedToMax = true;
            mod.add(r);
          }
        }
      }
      if (changed) {
        if (mod.isEmpty()) {
          return;
        }
        canvasAction = new ModelReorderAction(getModel(), mod);
      }
    }

    if (canvasAction instanceof ModelAddAction) {
      ModelAddAction addAction = (ModelAddAction) canvasAction;
      int cur = addAction.getDestinationIndex();
      int max = getMaxIndex(getModel());
      if (cur > max) {
        canvasAction = new ModelAddAction(getModel(), addAction.getObjects(), max + 1);
      }
    }

    proj.doAction(new CanvasActionAdapter(circuit, canvasAction));
  }
 Circuit getCircuit() {
   return circuitState.getCircuit();
 }
 public void setCircuit(Project proj, CircuitState circuitState) {
   this.proj = proj;
   this.circuitState = circuitState;
   Circuit circuit = circuitState.getCircuit();
   setModel(circuit.getAppearance(), this);
 }