Development Class Java

/********************************************************************
 Copyright (c) 1996 Artima Software Company. All Rights Reserved.
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for EVALUATION purposes only
 * is hereby granted provided that this copyright notice
 * appears in all copies. "Evaluation purposes" are any uses which
 * do not constitute the sale, sharing, or redistribution of this
 * software with or to any other persons in any medium.
 *
 * ARTIMA SOFTWARE COMPANY MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT
 * THE SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. ARTIMA SOFTWARE COMPANY
 * SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
 * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 PROJECT:  JavaWorld
 MODULE:   Under The Hood
 FILE:   CircleOfSquares.java
 AUTHOR:   Bill Venners, August 1996
 DESCRIPTION:
 This file contains all the code for the java virtual machine simulation
 applet, named Circle Of Squares, that accompanies the Under The Hood article
 titled, "Floating Point Arithmetic".
 As I developed this applet I had every class in a separate file. I combined
 them in one file here to make it easier to download.
 *********************************************************************/
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Label;
import java.awt.LayoutManager;
import java.awt.Panel;
public class CircleOfSquares extends java.applet.Applet {
  // Vars for the three outer panels that are contained inside the Applet's
  // panel.
  // twoParts contains the stack and the method area. simulationController
  // contains the Step and Reset buttons and the hint label.
  private ThreeParts threeParts;
  private RegisterPanel registers;
  private ControlPanel simulationController;
  // Local reference to reset button on control panel allows for easy enabling
  // and
  // disabling of this button.
  private Button resetButton;
  // Vars that implement the Java stack
  private final int stackBase = 0x33330000;
  private final int stackMemorySectionSize = 8;
  private StackMemorySection stackMemorySection = new StackMemorySection(stackBase,
      stackMemorySectionSize);
  private StackMemoryView stackMemoryView;
  // Vars that implement the method area of the JVM
  private final int methodAreaBase = 0x44440000;
  private MemorySection methodAreaMemorySection = new MemorySection(methodAreaBase,
      SimData.methodAreaMemorySectionSize);
  private MemoryView methodAreaMemoryView;
  // Vars that implement the Java registers
  private int pcRegister;
  private int optopRegister;
  private int frameRegister;
  private int varsRegister;
  public void init() {
    setBackground(ColorTable.appletBackgroundColor);
    setLayout(new BorderLayout(5, 5));
    threeParts = new ThreeParts(SimData.methodAreaMemorySectionSize);
    simulationController = new ControlPanel();
    resetButton = simulationController.getResetButton();
    ColoredLabel title = new ColoredLabel(StringTable.appletTitle, Label.CENTER,
        ColorTable.titleColor);
    title.setFont(new Font("Helvetica", Font.BOLD, 12));
    add("North", title);
    add("South", simulationController);
    add("Center", threeParts);
    // Get a reference to the UI objects that are actually manipulated by
    // the handlers of the Step and Reset buttons. These aren't available
    // without this explicit get() because these objects are buried several
    // levels down in embedded panels.
    stackMemoryView = threeParts.getStackMemoryViewReference();
    methodAreaMemoryView = threeParts.getMethodAreaMemoryViewReference();
    registers = threeParts.getRegisterPanel();
    // Place the bytecodes into the method area
    for (int i = 0; i < SimData.methodAreaMemorySectionSize; ++i) {
      methodAreaMemorySection.setAtAddress(methodAreaBase + i, SimData.theProgram[i]);
      methodAreaMemorySection.setLogicalValueAtAddress(methodAreaBase + i,
          SimData.byteCodeMnemonics[i]);
    }
    ResetState();
    UpdateStateDisplay();
  }
  public boolean action(Event evt, Object arg) {
    if (evt.target instanceof Button) {
      String bname = (String) arg;
      if (bname.equals(StringTable.reset)) {
        resetButton.disable();
        ResetState();
        UpdateStateDisplay();
      } else if (bname.equals(StringTable.step)) {
        if (!resetButton.isEnabled()) {
          resetButton.enable();
        }
        ExecuteNextInstruction();
        UpdateStateDisplay();
      }
    }
    return true;
  }
  // ExecuteNextInstruction() grabs the instruction pointed to by the program
  // counter, decodes it via the switch statement, and executes it by running
  // the
  // code under the appropriate case statement. The program counter is always
  // set to the next instruction that should be executed, naturally. Only those
  // bytecodes that appear in the short sequence presented in this simulation
  // are interpreted here to save time (your time in downloading and my time
  // in writing.)
  void ExecuteNextInstruction() {
    int a, b, result, i;
    float fa, fb, fresult;
    Float f;
    int operand0, operand1;
    int nextOpCode = methodAreaMemorySection.getAtAddress(pcRegister);
    switch (nextOpCode) {
    case OpCode.BIPUSH:
      operand0 = methodAreaMemorySection.getAtAddress(pcRegister + 1);
      stackMemorySection.setAtAddress(optopRegister, operand0);
      stackMemorySection.setLogicalValueAtAddress(optopRegister, StringTable.operand);
      optopRegister += 4;
      pcRegister += 2;
      break;
    case OpCode.FCONST_0:
      stackMemorySection.setAtAddress(optopRegister, Float.floatToIntBits((float) 0));
      stackMemorySection.setLogicalValueAtAddress(optopRegister, "0");
      optopRegister += 4;
      ++pcRegister;
      break;
    case OpCode.FCONST_2:
      stackMemorySection.setAtAddress(optopRegister, Float.floatToIntBits((float) 2));
      stackMemorySection.setLogicalValueAtAddress(optopRegister, "2");
      optopRegister += 4;
      ++pcRegister;
      break;
    case OpCode.FLOAD_0:
      a = stackMemorySection.getAtAddress(varsRegister);
      stackMemorySection.setAtAddress(optopRegister, a);
      fa = Float.intBitsToFloat(a);
      stackMemorySection.setLogicalValueAtAddress(optopRegister, Float.toString(fa));
      optopRegister += 4;
      ++pcRegister;
      break;
    case OpCode.FMUL:
      optopRegister -= 4;
      a = stackMemorySection.getAtAddress(optopRegister);
      fa = Float.intBitsToFloat(a);
      stackMemorySection.setLogicalValueAtAddress(optopRegister, "");
      optopRegister -= 4;
      b = stackMemorySection.getAtAddress(optopRegister);
      fb = Float.intBitsToFloat(b);
      fresult = fa * fb;
      result = Float.floatToIntBits(fresult);
      stackMemorySection.setAtAddress(optopRegister, result);
      stackMemorySection.setLogicalValueAtAddress(optopRegister, Float.toString(fresult));
      optopRegister += 4;
      ++pcRegister;
      break;
    case OpCode.FSTORE_0:
      optopRegister -= 4;
      a = stackMemorySection.getAtAddress(optopRegister);
      stackMemorySection.setLogicalValueAtAddress(optopRegister, "");
      stackMemorySection.setAtAddress(varsRegister, a);
      fa = Float.intBitsToFloat(a);
      stackMemorySection.setLogicalValueAtAddress(varsRegister, Float.toString(fa));
      ++pcRegister;
      break;
    case OpCode.FSUB:
      optopRegister -= 4;
      a = stackMemorySection.getAtAddress(optopRegister);
      fa = Float.intBitsToFloat(a);
      stackMemorySection.setLogicalValueAtAddress(optopRegister, "");
      optopRegister -= 4;
      b = stackMemorySection.getAtAddress(optopRegister);
      fb = Float.intBitsToFloat(b);
      fresult = fb - fa;
      result = Float.floatToIntBits(fresult);
      stackMemorySection.setAtAddress(optopRegister, result);
      stackMemorySection.setLogicalValueAtAddress(optopRegister, Float.toString(fresult));
      optopRegister += 4;
      ++pcRegister;
      break;
    case OpCode.GOTO:
      operand1 = methodAreaMemorySection.getAtAddress(pcRegister + 1);
      operand0 = methodAreaMemorySection.getAtAddress(pcRegister + 2);
      int offset = (operand1 << 8) | (operand0 & 0xff);
      pcRegister += offset;
      break;
    case OpCode.IADD:
      optopRegister -= 4;
      a = stackMemorySection.getAtAddress(optopRegister);
      stackMemorySection.setLogicalValueAtAddress(optopRegister, "");
      optopRegister -= 4;
      b = stackMemorySection.getAtAddress(optopRegister);
      result = a + b;
      stackMemorySection.setAtAddress(optopRegister, result);
      optopRegister += 4;
      ++pcRegister;
      break;
    case OpCode.ICONST_M1:
      stackMemorySection.setAtAddress(optopRegister, -1);
      stackMemorySection.setLogicalValueAtAddress(optopRegister, StringTable.operand);
      optopRegister += 4;
      ++pcRegister;
      break;
    case OpCode.ICONST_0:
      stackMemorySection.setAtAddress(optopRegister, 0);
      stackMemorySection.setLogicalValueAtAddress(optopRegister, StringTable.operand);
      optopRegister += 4;
      ++pcRegister;
      break;
    case OpCode.ICONST_1:
      stackMemorySection.setAtAddress(optopRegister, 1);
      stackMemorySection.setLogicalValueAtAddress(optopRegister, StringTable.operand);
      optopRegister += 4;
      ++pcRegister;
      break;
    case OpCode.ICONST_2:
      stackMemorySection.setAtAddress(optopRegister, 2);
      stackMemorySection.setLogicalValueAtAddress(optopRegister, StringTable.operand);
      optopRegister += 4;
      ++pcRegister;
      break;
    case OpCode.IINC:
      operand0 = methodAreaMemorySection.getAtAddress(pcRegister + 1);
      operand1 = methodAreaMemorySection.getAtAddress(pcRegister + 2);
      a = stackMemorySection.getAtAddress(varsRegister + (operand0 * 4));
      a += operand1;
      stackMemorySection.setAtAddress(varsRegister + (operand0 * 4), a);
      pcRegister += 3;
      break;
    case OpCode.ILOAD_0:
      a = stackMemorySection.getAtAddress(varsRegister);
      stackMemorySection.setAtAddress(optopRegister, a);
      stackMemorySection.setLogicalValueAtAddress(optopRegister, StringTable.operand);
      optopRegister += 4;
      ++pcRegister;
      break;
    case OpCode.ILOAD_1:
      a = stackMemorySection.getAtAddress(varsRegister + 4);
      stackMemorySection.setAtAddress(optopRegister, a);
      stackMemorySection.setLogicalValueAtAddress(optopRegister, StringTable.operand);
      optopRegister += 4;
      ++pcRegister;
      break;
    case OpCode.IMUL:
      optopRegister -= 4;
      a = stackMemorySection.getAtAddress(optopRegister);
      stackMemorySection.setLogicalValueAtAddress(optopRegister, "");
      optopRegister -= 4;
      b = stackMemorySection.getAtAddress(optopRegister);
      result = a * b;
      stackMemorySection.setAtAddress(optopRegister, result);
      optopRegister += 4;
      ++pcRegister;
      break;
    case OpCode.INT2BYTE:
      a = stackMemorySection.getAtAddress(optopRegister - 4);
      a = (byte) a;
      stackMemorySection.setAtAddress(optopRegister - 4, a);
      stackMemorySection.setLogicalValueAtAddress(optopRegister - 4, StringTable.operand);
      ++pcRegister;
      break;
    case OpCode.ISTORE_0:
      optopRegister -= 4;
      a = stackMemorySection.getAtAddress(optopRegister);
      stackMemorySection.setLogicalValueAtAddress(optopRegister, "");
      stackMemorySection.setAtAddress(varsRegister, a);
      ++pcRegister;
      break;
    case OpCode.ISTORE_1:
      optopRegister -= 4;
      a = stackMemorySection.getAtAddress(optopRegister);
      stackMemorySection.setLogicalValueAtAddress(optopRegister + 4, "");
      stackMemorySection.setAtAddress(varsRegister + 4, a);
      ++pcRegister;
      break;
    }
  }
  // Pushing the Reset button will cause ResetState() to be executed, which will
  // reset all the data to its initial values.
  void ResetState() {
    pcRegister = methodAreaBase;
    optopRegister = stackBase + SimData.optopOffset;
    frameRegister = stackBase + SimData.frameOffset;
    varsRegister = stackBase;
    int i;
    for (i = 0; i < 7; ++i) {
      stackMemorySection.setLogicalValueAtAddress(stackBase + (i * 4), "");
      stackMemorySection.setAtAddress(stackBase + (i * 4), 0);
    }
    methodAreaMemoryView.update(methodAreaMemorySection, methodAreaBase);
  }
  // UpdateStateDisplay writes the current state of the JVM to the UI.
  void UpdateStateDisplay() {
    registers.setPcRegister(pcRegister);
    registers.setOptopRegister(optopRegister);
    registers.setFrameRegister(frameRegister);
    registers.setVarsRegister(varsRegister);
    stackMemoryView.update(stackMemorySection, stackBase);
    methodAreaMemoryView.updateProgramCounter(pcRegister - methodAreaBase, methodAreaMemorySection);
    stackMemoryView.clearPointers();
    stackMemoryView.updatePointer((varsRegister - stackBase) / 4, StringTable.varsPointer);
    stackMemoryView.updatePointer((frameRegister - stackBase) / 4, StringTable.framePointer);
    stackMemoryView.updatePointer((optopRegister - stackBase) / 4, StringTable.optopPointer);
    int nextOpCode = methodAreaMemorySection.getAtAddress(pcRegister);
    switch (nextOpCode) {
    case OpCode.BIPUSH:
      simulationController.setExplanationText(StringTable.bipushText);
      break;
    case OpCode.FCONST_0:
      simulationController.setExplanationText(StringTable.fconst_0Text);
      break;
    case OpCode.FCONST_2:
      simulationController.setExplanationText(StringTable.fconst_2Text);
      break;
    case OpCode.FLOAD_0:
      simulationController.setExplanationText(StringTable.fload_0Text);
      break;
    case OpCode.FMUL:
      simulationController.setExplanationText(StringTable.fmulText);
      break;
    case OpCode.FSTORE_0:
      simulationController.setExplanationText(StringTable.fstore_0Text);
      break;
    case OpCode.FSUB:
      simulationController.setExplanationText(StringTable.fsubText);
      break;
    case OpCode.GOTO:
      simulationController.setExplanationText(StringTable.gotoText);
      break;
    case OpCode.IADD:
      simulationController.setExplanationText(StringTable.iaddText);
      break;
    case OpCode.ICONST_M1:
      simulationController.setExplanationText(StringTable.iconst_m1Text);
      break;
    case OpCode.ICONST_0:
      simulationController.setExplanationText(StringTable.iconst_0Text);
      break;
    case OpCode.ICONST_1:
      simulationController.setExplanationText(StringTable.iconst_1Text);
      break;
    case OpCode.ICONST_2:
      simulationController.setExplanationText(StringTable.iconst_2Text);
      break;
    case OpCode.IINC:
      simulationController.setExplanationText(StringTable.iincText);
      break;
    case OpCode.ILOAD_0:
      simulationController.setExplanationText(StringTable.iload_0Text);
      break;
    case OpCode.ILOAD_1:
      simulationController.setExplanationText(StringTable.iload_1Text);
      break;
    case OpCode.IMUL:
      simulationController.setExplanationText(StringTable.imulText);
      break;
    case OpCode.INT2BYTE:
      simulationController.setExplanationText(StringTable.int2byteText);
      break;
    case OpCode.ISTORE_0:
      simulationController.setExplanationText(StringTable.istore_0Text);
      break;
    case OpCode.ISTORE_1:
      simulationController.setExplanationText(StringTable.istore_1Text);
      break;
    default:
      simulationController.setExplanationText("");
      break;
    }
  }
  // Make pretty border around entire applet panel
  public Insets insets() {
    return new Insets(5, 5, 5, 5);
  }
}
// I used this class because I can't seem to set the background color of
// a label. I only want a label, but I want the backgound to be gray.
class ColoredLabel extends Panel {
  private Label theLabel;
  ColoredLabel(String label, int alignment, Color color) {
    setLayout(new GridLayout(1, 1));
    setBackground(color);
    theLabel = new Label(label, alignment);
    add(theLabel);
  }
  public void setLabelText(String s) {
    theLabel.setText(s);
  }
  public Insets insets() {
    return new Insets(0, 0, 0, 0);
  }
}
class ColorTable {
  static final Color appletBackgroundColor = Color.blue;
  static final Color registersAreaColor = Color.magenta;
  static final Color stackAreaColor = Color.magenta;
  static final Color methodAreaColor = Color.magenta;
  static final Color titleColor = Color.cyan;
  static final Color explanationLabel = Color.cyan;
}
class ControlPanel extends Panel {
  private ColoredLabel explanationLabel;
  private GrayButton resetButton = new GrayButton(StringTable.reset);
  ControlPanel() {
    setLayout(new BorderLayout(5, 5));
    Panel leftButtonPanel = new Panel();
    leftButtonPanel.setLayout(new GridLayout(2, 1, 0, 5));
    leftButtonPanel.add(new GrayButton(StringTable.step));
    resetButton.disable();
    leftButtonPanel.add(resetButton);
    explanationLabel = new ColoredLabel("This is where the explanation goes...", Label.CENTER,
        Color.lightGray);
    explanationLabel.setBackground(ColorTable.explanationLabel);
    Font plainFont = new Font("TimesRoman", Font.ITALIC, 12);
    explanationLabel.setFont(plainFont);
    add("West", leftButtonPanel);
    add("Center", explanationLabel);
  }
  public void setExplanationText(String explanation) {
    explanationLabel.setLabelText(explanation);
  }
  public Button getResetButton() {
    return resetButton;
  }
  public Insets insets() {
    // top, left, bottom, right
    return new Insets(0, 0, 0, 0);
  }
}
class GrayButton extends Button {
  GrayButton(String label) {
    super(label);
    setBackground(Color.lightGray);
  }
}
// GridSnapLayout lays out components in a grid that can have columns of
// varying width. This is not a very general purpose layout manager. It
// solves the specific problem of getting all the information I want to display
// about
// the stack and method areas in a nice grid. Because some columns of info need
// more room than others, and space is limited on a web page, I needed to be
// able to specify varying widths of columns in a grid.
class GridSnapLayout implements LayoutManager {
  // rows and cols are the number of rows and columns of the grid upon
  // which the components are placed. Components are always one row
  // in height, but may be more than one column in width. The number
  // of columns width of each component is stored in hComponentCellWidths.
  // The array length of hComponentCellWidths indicates the number of
  // components that will appear on each row.
  private int rows;
  private int cols;
  private int[] hComponentCellWidths;
  public GridSnapLayout(int rows, int cols, int[] hComponentCellWidths) {
    this.rows = rows;
    this.cols = cols;
    this.hComponentCellWidths = hComponentCellWidths;
  }
  public void addLayoutComponent(String name, Component comp) {
  }
  public void removeLayoutComponent(Component comp) {
  }
  // Calculate preferred size as if each component were taking an equal
  // share of the width of a row.
  public Dimension preferredLayoutSize(Container parent) {
    int rowCount = rows;
    int colCount = cols;
    Insets parentInsets = parent.insets();
    int componentCount = parent.countComponents();
    if (rowCount > 0) {
      colCount = (componentCount + rowCount - 1) / rowCount;
    } else {
      rowCount = (componentCount + colCount - 1) / colCount;
    }
    // Find the maximum preferred width and the maximum preferred height
    // of any component.
    int w = 0;
    int h = 0;
    for (int i = 0; i < componentCount; i++) {
      Component comp = parent.getComponent(i);
      Dimension d = comp.preferredSize();
      if (w < d.width) {
        w = d.width;
      }
      if (h < d.height) {
        h = d.height;
      }
    }
    // Return the maximum preferred component width and height times the number
    // of columns and rows, respectively, plus any insets in the parent.
    return new Dimension(parentInsets.left + parentInsets.right + colCount * w, parentInsets.top
        + parentInsets.bottom + rowCount * h);
  }
  // Calculate minimum size as if each component were taking an equal
  // share of the width of a row.
  public Dimension minimumLayoutSize(Container parent) {
    Insets parentInsets = parent.insets();
    int componentCount = parent.countComponents();
    int rowCount = rows;
    int colCount = cols;
    if (rowCount > 0) {
      colCount = (componentCount + rowCount - 1) / rowCount;
    } else {
      rowCount = (componentCount + colCount - 1) / colCount;
    }
    // Find the maximum "minimum width" and the maximum "minimum height"
    // of any component.
    int w = 0;
    int h = 0;
    for (int i = 0; i < componentCount; i++) {
      Component comp = parent.getComponent(i);
      Dimension d = comp.minimumSize();
      if (w < d.width) {
        w = d.width;
      }
      if (h < d.height) {
        h = d.height;
      }
    }
    // Return the maximum "minimum component width and height" times the number
    // of columns and rows, respectively, plus any insets in the parent.
    return new Dimension(parentInsets.left + parentInsets.right + colCount * w, parentInsets.top
        + parentInsets.bottom + rowCount * h);
  }
  // Layout the container such that the widths of columns correspond
  // to the number of columns in that components hComponentCellWidth
  // array element. For example, if the
  public void layoutContainer(Container parent) {
    int rowCount = rows;
    int colCount = hComponentCellWidths.length;
    Insets parentInsets = parent.insets();
    int componentCount = parent.countComponents();
    if (componentCount == 0) {
      return;
    }
    // Calculate the width and height of each grid cell. The height will
    // be the height of each component, but the width may not. The width
    // of a component will be some multiple of a grid cell width. The
    // number of grid cells for each component is defined by the
    // hComponentCellWidths array. w is width of each grid cell. h is
    // height of each grid cell.
    Dimension parentDim = parent.size();
    int w = parentDim.width - (parentInsets.left + parentInsets.right);
    int h = parentDim.height - (parentInsets.top + parentInsets.bottom);
    w /= cols;
    h /= rowCount;
    // For each row and column of components (not grid cells) position
    // the component.
    for (int c = 0, x = parentInsets.left; c < colCount; c++) {
      for (int r = 0, y = parentInsets.top; r < rowCount; r++) {
        int i = r * colCount + c;
        if (i < componentCount) {
          parent.getComponent(i).reshape(x, y, w * hComponentCellWidths[c], h);
        }
        y += h;
      }
      x += (w * hComponentCellWidths[c]);
    }
  }
}
class HexString {
  private final String hexChar = "0123456789abcdef";
  private StringBuffer buf = new StringBuffer();
  void Convert(int val, int maxNibblesToConvert) {
    buf.setLength(0);
    int v = val;
    for (int i = 0; i < maxNibblesToConvert; ++i) {
      if (v == 0) {
        if (i == 0) {
          buf.insert(0, '0');
        }
        break;
      }
      // Get lowest nibble
      int remainder = v & 0xf;
      // Convert nibble to a character and insert it into the beginning of the
      // string
      buf.insert(0, hexChar.charAt(remainder));
      // Shift the int to the right four bits
      v >>>= 4;
    }
  }
  HexString(int val, int minWidth) {
    Convert(val, minWidth);
    int charsNeeded = minWidth - buf.length();
    for (int i = 0; i < charsNeeded; ++i) {
      buf.insert(0, '0');
    }
  }
  public String getString() {
    return buf.toString();
  }
}
class LabeledRegister extends Panel {
  private ColoredLabel registerContents;
  LabeledRegister(String labelText) {
    setLayout(new BorderLayout(5, 5));
    registerContents = new ColoredLabel("00000000", Label.CENTER, Color.lightGray);
    registerContents.setFont(new Font("TimesRoman", Font.PLAIN, 11));
    Label title = new Label(labelText, Label.RIGHT);
    title.setFont(new Font("Helvetica", Font.ITALIC, 11));
    add("East", registerContents);
    add("Center", title);
  }
  public void setRegister(int val) {
    HexString hexString = new HexString(val, 8);
    registerContents.setLabelText(hexString.getString());
  }
  public Insets insets() {
    return new Insets(0, 0, 0, 0);
  }
}
// MemorySection is just used for the method area in this applet. This
// implements
// the functionality of the method area and has nothing to do with the UI.
class MemorySection {
  private int[] memory;
  private int baseAddress;
  private String[] logicalValueString;
  MemorySection(int base, int size) {
    baseAddress = base;
    memory = new int[size];
    logicalValueString = new String[size];
    for (int i = 0; i < size; ++i) {
      logicalValueString[i] = new String();
    }
  }
  int getBaseAddress() {
    return baseAddress;
  }
  public int getAtAddress(int address) {
    return memory[address - baseAddress];
  }
  public String getLogicalValueAtAddress(int address) {
    return logicalValueString[address - baseAddress];
  }
  public void setAtAddress(int address, int value) {
    memory[address - baseAddress] = value;
  }
  public void setLogicalValueAtAddress(int address, String s) {
    logicalValueString[address - baseAddress] = s;
  }
  int getSize() {
    return memory.length;
  }
}
// MemoryView is just used for the method area in this applet. It implements the
// UI of the method area.
class MemoryView extends Panel {
  private final int memoryLocationsVisibleCount = SimData.methodAreaMemoryLocationsVisibleCount;
  private Label[] pointer = new Label[memoryLocationsVisibleCount];
  private Label[] address = new Label[memoryLocationsVisibleCount];
  private Label[] byteValue = new Label[memoryLocationsVisibleCount];
  private Label[] logicalValue = new Label[memoryLocationsVisibleCount];
  private int firstVisibleRow;
  private int currentProgramCounterRow;
  MemoryView(int methodAreaMemSectionSize) {
    setLayout(new GridLayout(memoryLocationsVisibleCount, 4));
    setBackground(Color.lightGray);
    Font plainFont = new Font("TimesRoman", Font.PLAIN, 11);
    setFont(plainFont);
    Font italicFont = new Font("TimesRoman", Font.ITALIC, 11);
    for (int i = 0; i < memoryLocationsVisibleCount; ++i) {
      pointer[i] = new Label("", Label.RIGHT);
      pointer[i].setFont(italicFont);
      add(pointer[i]);
      address[i] = new Label("", Label.CENTER);
      add(address[i]);
      byteValue[i] = new Label("", Label.CENTER);
      add(byteValue[i]);
      logicalValue[i] = new Label("", Label.LEFT);
      add(logicalValue[i]);
    }
  }
  public void setAt(int i, int addressValue, int value, String logicalValueStr) {
    HexString addressValueHexString = new HexString(addressValue, 8);
    HexString byteValueHexString = new HexString(value, 2);
    address[i].setText(addressValueHexString.getString());
    byteValue[i].setText(byteValueHexString.getString());
    logicalValue[i].setText(logicalValueStr);
  }
  public void update(MemorySection memorySection, int initialAddress) {
    for (int i = 0; i < memoryLocationsVisibleCount; ++i) {
      int theByte = memorySection.getAtAddress(initialAddress + i);
      String logicalValue = memorySection.getLogicalValueAtAddress(initialAddress + i);
      setAt(i, initialAddress + i, theByte, logicalValue);
    }
  }
  public void clearPointers() {
    for (int i = 0; i < memoryLocationsVisibleCount; ++i) {
      pointer[i].setText("");
    }
  }
  public void updateProgramCounter(int i, MemorySection memorySection) {
    pointer[currentProgramCounterRow - firstVisibleRow].setText("");
    if (i - firstVisibleRow >= memoryLocationsVisibleCount) {
      firstVisibleRow += 5;
      if (firstVisibleRow > memorySection.getSize() - memoryLocationsVisibleCount) {
        firstVisibleRow = memorySection.getSize() - memoryLocationsVisibleCount;
      }
      update(memorySection, memorySection.getBaseAddress() + firstVisibleRow);
    } else if (i < firstVisibleRow) {
      firstVisibleRow = i;
      update(memorySection, memorySection.getBaseAddress() + firstVisibleRow);
    }
    pointer[i - firstVisibleRow].setText("pc >");
    currentProgramCounterRow = i;
  }
  public Insets insets() {
    // top, left, bottom, right
    return new Insets(0, 0, 0, 0);
  }
}
class MemoryViewTitlePanel extends Panel {
  MemoryViewTitlePanel() {
    setLayout(new GridLayout(1, 4));
    setFont(new Font("Helvetica", Font.ITALIC, 11));
    add(new Label("", Label.CENTER));
    add(new Label(StringTable.address, Label.CENTER));
    add(new Label(StringTable.bytecodes, Label.CENTER));
    add(new Label(StringTable.mnemonics, Label.CENTER));
  }
  public Insets insets() {
    // top, left, bottom, right
    return new Insets(0, 0, 0, 0);
  }
}
class MemoryViewWithTitles extends Panel {
  private MemoryView memoryView;
  MemoryViewWithTitles(int methodAreaMemorySectionSize) {
    memoryView = new MemoryView(methodAreaMemorySectionSize);
    setLayout(new BorderLayout());
    add("North", new MemoryViewTitlePanel());
    add("Center", memoryView);
  }
  public MemoryView getMemoryViewReference() {
    return memoryView;
  }
  public Insets insets() {
    // top, left, bottom, right
    return new Insets(0, 0, 0, 0);
  }
}
class MethodAreaPanel extends Panel {
  private Label title;
  private MemoryViewWithTitles memoryView;
  MethodAreaPanel(int methodAreaMemorySectionSize) {
    memoryView = new MemoryViewWithTitles(methodAreaMemorySectionSize);
    setLayout(new BorderLayout());
    title = new Label("Method Area", Label.CENTER);
    title.setFont(new Font("Helvetica", Font.BOLD, 11));
    add("North", title);
    add("Center", memoryView);
  }
  public MemoryView getMemoryViewReference() {
    return memoryView.getMemoryViewReference();
  }
  public Insets insets() {
    return new Insets(5, 5, 5, 5);
  }
}
class OpCode {
  final static int NOP = 0;
  final static int ACONST_NULL = 1;
  final static int ICONST_M1 = 2;
  final static int ICONST_0 = 3;
  final static int ICONST_1 = 4;
  final static int ICONST_2 = 5;
  final static int ICONST_3 = 6;
  final static int ICONST_4 = 7;
  final static int ICONST_5 = 8;
  final static int LCONST_0 = 9;
  final static int LCONST_1 = 10;
  final static int FCONST_0 = 11;
  final static int FCONST_1 = 12;
  final static int FCONST_2 = 13;
  final static int DCONST_0 = 14;
  final static int DCONST_1 = 15;
  final static int BIPUSH = 16;
  final static int SIPUSH = 17;
  final static int LDC1 = 18;
  final static int LDC2 = 19;
  final static int LDC2W = 20;
  final static int ILOAD = 21;
  final static int LLOAD = 22;
  final static int FLOAD = 23;
  final static int DLOAD = 24;
  final static int ALOAD = 25;
  final static int ILOAD_0 = 26;
  final static int ILOAD_1 = 27;
  final static int ILOAD_2 = 28;
  final static int ILOAD_3 = 29;
  final static int LLOAD_0 = 30;
  final static int LLOAD_1 = 31;
  final static int LLOAD_2 = 32;
  final static int LLOAD_3 = 33;
  final static int FLOAD_0 = 34;
  final static int FLOAD_1 = 35;
  final static int FLOAD_2 = 36;
  final static int FLOAD_3 = 37;
  final static int DLOAD_0 = 38;
  final static int DLOAD_1 = 39;
  final static int DLOAD_2 = 40;
  final static int DLOAD_3 = 41;
  final static int ALOAD_0 = 42;
  final static int ALOAD_1 = 43;
  final static int ALOAD_2 = 44;
  final static int ALOAD_3 = 45;
  final static int IALOAD = 46;
  final static int LALOAD = 47;
  final static int FALOAD = 48;
  final static int DALOAD = 49;
  final static int AALOAD = 50;
  final static int BALOAD = 51;
  final static int CALOAD = 52;
  final static int SALOAD = 53;
  final static int ISTORE = 54;
  final static int LSTORE = 55;
  final static int FSTORE = 56;
  final static int DSTORE = 57;
  final static int ASTORE = 58;
  final static int ISTORE_0 = 59;
  final static int ISTORE_1 = 60;
  final static int ISTORE_2 = 61;
  final static int ISTORE_3 = 62;
  final static int LSTORE_0 = 63;
  final static int LSTORE_1 = 64;
  final static int LSTORE_2 = 65;
  final static int LSTORE_3 = 66;
  final static int FSTORE_0 = 67;
  final static int FSTORE_1 = 68;
  final static int FSTORE_2 = 69;
  final static int FSTORE_3 = 70;
  final static int DSTORE_0 = 71;
  final static int DSTORE_1 = 72;
  final static int DSTORE_2 = 73;
  final static int DSTORE_3 = 74;
  final static int ASTORE_0 = 75;
  final static int ASTORE_1 = 76;
  final static int ASTORE_2 = 77;
  final static int ASTORE_3 = 78;
  final static int IASTORE = 79;
  final static int LASTORE = 80;
  final static int FASTORE = 81;
  final static int DASTORE = 82;
  final static int AASTORE = 83;
  final static int BASTORE = 84;
  final static int CASTORE = 85;
  final static int SASTORE = 86;
  final static int POP = 87;
  final static int POP2 = 88;
  final static int DUP = 89;
  final static int DUP_X1 = 90;
  final static int DUP_X2 = 91;
  final static int DUP2 = 92;
  final static int DUP2_X1 = 93;
  final static int DUP2_X2 = 94;
  final static int SWAP = 95;
  final static int IADD = 96;
  final static int LADD = 97;
  final static int FADD = 98;
  final static int DADD = 99;
  final static int ISUB = 100;
  final static int LSUB = 101;
  final static int FSUB = 102;
  final static int DSUB = 103;
  final static int IMUL = 104;
  final static int LMUL = 105;
  final static int FMUL = 106;
  final static int DMUL = 107;
  final static int IDIV = 108;
  final static int LDIV = 109;
  final static int FDIV = 110;
  final static int DDIV = 111;
  final static int IREM = 112;
  final static int LREM = 113;
  final static int FREM = 114;
  final static int DREM = 115;
  final static int INEG = 116;
  final static int LNEG = 117;
  final static int FNEG = 118;
  final static int DNEG = 119;
  final static int ISHL = 120;
  final static int LSHL = 121;
  final static int ISHR = 122;
  final static int LSHR = 123;
  final static int IUSHR = 124;
  final static int LUSHR = 125;
  final static int IAND = 126;
  final static int LAND = 127;
  final static int IOR = 128;
  final static int LOR = 129;
  final static int IXOR = 130;
  final static int LXOR = 131;
  final static int IINC = 132;
  final static int I2L = 133;
  final static int I2F = 134;
  final static int I2D = 135;
  final static int L2I = 136;
  final static int L2F = 137;
  final static int L2D = 138;
  final static int F2I = 139;
  final static int F2L = 140;
  final static int F2D = 141;
  final static int D2I = 142;
  final static int D2L = 143;
  final static int D2F = 144;
  final static int INT2BYTE = 145;
  final static int INT2CHAR = 146;
  final static int INT2SHORT = 147;
  final static int LCMP = 148;
  final static int FCMPL = 149;
  final static int FCMPG = 150;
  final static int DCMPL = 151;
  final static int DCMPG = 152;
  final static int IFEQ = 153;
  final static int IFNE = 154;
  final static int IFLT = 155;
  final static int IFGE = 156;
  final static int IFGT = 157;
  final static int IFLE = 158;
  final static int IF_ICMPEQ = 159;
  final static int IF_ICMPNE = 160;
  final static int IF_ICMPLT = 161;
  final static int IF_ICMPGT = 163;
  final static int IF_ICMPLE = 164;
  final static int IF_ICMPGE = 162;
  final static int IF_ACMPEQ = 165;
  final static int IF_ACMPNE = 166;
  final static int GOTO = 167;
  final static int JSR = 168;
  final static int RET = 169;
  final static int TABLESWITCH = 170;
  final static int LOOKUPSWITCH = 171;
  final static int IRETURN = 172;
  final static int LRETURN = 173;
  final static int FRETURN = 174;
  final static int DRETURN = 175;
  final static int ARETURN = 176;
  final static int RETURN = 177;
  final static int INVOKEVIRTUAL = 182;
  final static int INVOKENONVIRTUAL = 183;
  final static int INVOKESTATIC = 184;
  final static int INVOKEINTERFACE = 185;
  final static int NEW = 187;
  final static int NEWARRAY = 188;
  final static int ANEWARRAY = 189;
  final static int ARRAYLENGTH = 190;
  final static int ATHROW = 191;
  final static int CHECKCAST = 192;
  final static int INSTANCEOF = 193;
  final static int MONITORENTER = 194;
  final static int MONITOREXIT = 195;
  final static int WIDE = 196;
  final static int MULTIANEWARRAY = 197;
  final static int IFNULL = 198;
  final static int IFNONNULL = 199;
  final static int GOTO_W = 200;
  final static int JSR_W = 201;
  final static int BREAKPOINT = 202;
  final static int RET_W = 209;
}
class PanelWithInsets extends Panel {
  private int top;
  private int left;
  private int bottom;
  private int right;
  PanelWithInsets(int t, int l, int b, int r) {
    top = t;
    left = l;
    bottom = b;
    right = r;
  }
  PanelWithInsets() {
    top = 5;
    left = 5;
    bottom = 5;
    right = 5;
  }
  public Insets insets() {
    return new Insets(top, left, bottom, right);
  }
}
class RegisterPanel extends Panel {
  private LabeledRegister pcRegister;
  private LabeledRegister optopRegister;
  private LabeledRegister frameRegister;
  private LabeledRegister varsRegister;
  RegisterPanel() {
    setLayout(new BorderLayout(5, 5));
    pcRegister = new LabeledRegister(StringTable.pc);
    optopRegister = new LabeledRegister(StringTable.optop);
    frameRegister = new LabeledRegister(StringTable.frame);
    varsRegister = new LabeledRegister(StringTable.vars);
    setBackground(ColorTable.registersAreaColor);
    Panel labeledRegisterPanel = new Panel();
    labeledRegisterPanel.setLayout(new GridLayout(1, 4, 5, 5));
    labeledRegisterPanel.add(pcRegister);
    labeledRegisterPanel.add(optopRegister);
    labeledRegisterPanel.add(frameRegister);
    labeledRegisterPanel.add(varsRegister);
    Label title = new Label(StringTable.Registers, Label.CENTER);
    title.setFont(new Font("Helvetica", Font.BOLD, 11));
    add("West", title);
    add("Center", labeledRegisterPanel);
  }
  public void setPcRegister(int val) {
    pcRegister.setRegister(val);
  }
  public void setOptopRegister(int val) {
    optopRegister.setRegister(val);
  }
  public void setFrameRegister(int val) {
    frameRegister.setRegister(val);
  }
  public void setVarsRegister(int val) {
    varsRegister.setRegister(val);
  }
  public Insets insets() {
    // top, left, bottom, right
    return new Insets(5, 5, 5, 5);
  }
}
class RepeaterButton extends GrayButton {
  RepeaterButton(String label) {
    super(label);
  }
}
class SimData {
  static final int methodAreaMemorySectionSize = 13;
  static final int methodAreaMemoryLocationsVisibleCount = 13;
  static final int frameOffset = 4;
  static final int optopOffset = 16;
  static int[] theProgram = { OpCode.FCONST_2, OpCode.FSTORE_0, OpCode.FLOAD_0, OpCode.FLOAD_0,
      OpCode.FMUL, OpCode.FSTORE_0, OpCode.FCONST_0, OpCode.FLOAD_0, OpCode.FSUB, OpCode.FSTORE_0,
      OpCode.GOTO, (byte) 0xff, (byte) 0xf8 };
  static String[] byteCodeMnemonics = { "fconst_2", "fstore_0", "fload_0", "fload_0", "fmul",
      "fstore_0", "fconst_0", "fload_0", "fsub", "fstore_0", "goto -17", "", "" };
}
// StackMemorySection is just used for the stack in this applet. This implements
// the functionality of the stack and has nothing to do with the UI.
class StackMemorySection {
  private int[] memory;
  private int baseAddress;
  private String[] logicalValueString;
  StackMemorySection(int base, int size) {
    baseAddress = base;
    memory = new int[size];
    logicalValueString = new String[size];
    for (int i = 0; i < size; ++i) {
      memory[i] = 0;
      logicalValueString[i] = new String();
    }
  }
  public int getAtAddress(int address) {
    return memory[(address - baseAddress) / 4];
  }
  public String getLogicalValueAtAddress(int address) {
    return logicalValueString[(address - baseAddress) / 4];
  }
  public void setAtAddress(int address, int value) {
    memory[(address - baseAddress) / 4] = value;
  }
  public void setLogicalValueAtAddress(int address, String s) {
    logicalValueString[(address - baseAddress) / 4] = s;
  }
}
// StackMemoryView is just used for the stack in this applet. It implements the
// UI of the stack.
class StackMemoryView extends Panel {
  private final int memoryLocationsVisibleCount = 8;
  private Label[] pointer = new Label[memoryLocationsVisibleCount];
  private Label[] address = new Label[memoryLocationsVisibleCount];
  private Label[] wordValue = new Label[memoryLocationsVisibleCount];
  private Label[] logicalValue = new Label[memoryLocationsVisibleCount];
  StackMemoryView() {
    int[] hComponentCellWidths = new int[4];
    hComponentCellWidths[0] = 2;
    hComponentCellWidths[1] = 2;
    hComponentCellWidths[2] = 2;
    hComponentCellWidths[3] = 3;
    setLayout(new GridSnapLayout(memoryLocationsVisibleCount, 9, hComponentCellWidths));
    setBackground(Color.lightGray);
    Font plainFont = new Font("TimesRoman", Font.PLAIN, 11);
    setFont(plainFont);
    Font italicFont = new Font("TimesRoman", Font.ITALIC, 11);
    for (int i = memoryLocationsVisibleCount - 1; i >= 0; --i) {
      pointer[i] = new Label("", Label.RIGHT);
      pointer[i].setFont(italicFont);
      add(pointer[i]);
      address[i] = new Label("", Label.CENTER);
      add(address[i]);
      wordValue[i] = new Label("", Label.CENTER);
      add(wordValue[i]);
      logicalValue[i] = new Label("", Label.CENTER);
      add(logicalValue[i]);
    }
  }
  public void setAt(int i, int addressValue, int value, String logicalValueString) {
    HexString addressValueString = new HexString(addressValue, 8);
    HexString wordValueString = new HexString(value, 8);
    address[memoryLocationsVisibleCount - 1 - i].setText(addressValueString.getString());
    wordValue[memoryLocationsVisibleCount - 1 - i].setText(wordValueString.getString());
    logicalValue[memoryLocationsVisibleCount - 1 - i].setText(logicalValueString);
  }
  public void update(StackMemorySection memorySection, int initialAddress) {
    for (int i = 0; i < memoryLocationsVisibleCount; ++i) {
      int theWord = memorySection.getAtAddress(initialAddress + (i * 4));
      String logicalValue = memorySection.getLogicalValueAtAddress(initialAddress + (i * 4));
      setAt(i, initialAddress + (i * 4), theWord, logicalValue);
    }
  }
  public void clearPointers() {
    for (int i = 0; i < memoryLocationsVisibleCount; ++i) {
      pointer[i].setText("");
    }
  }
  public void updatePointer(int i, String pointerString) {
    pointer[memoryLocationsVisibleCount - 1 - i].setText(pointerString);
  }
  public Insets insets() {
    // top, left, bottom, right
    return new Insets(0, 0, 0, 0);
  }
}
class StackMemoryViewTitlePanel extends Panel {
  StackMemoryViewTitlePanel() {
    // setLayout(new GridLayout(1, 4));
    int[] hComponentCellWidths = new int[4];
    hComponentCellWidths[0] = 2;
    hComponentCellWidths[1] = 2;
    hComponentCellWidths[2] = 2;
    hComponentCellWidths[3] = 3;
    setLayout(new GridSnapLayout(1, 9, hComponentCellWidths));
    setFont(new Font("Helvetica", Font.ITALIC, 11));
    add(new Label("", Label.CENTER));
    add(new Label(StringTable.address, Label.CENTER));
    add(new Label(StringTable.hexValue, Label.CENTER));
    add(new Label(StringTable.value, Label.CENTER));
  }
  public Insets insets() {
    // top, left, bottom, right
    return new Insets(0, 0, 0, 0);
  }
}
class StackMemoryViewWithTitles extends Panel {
  private StackMemoryView memoryView = new StackMemoryView();
  StackMemoryViewWithTitles() {
    setLayout(new BorderLayout());
    add("North", new StackMemoryViewTitlePanel());
    add("Center", memoryView);
  }
  public StackMemoryView getMemoryViewReference() {
    return memoryView;
  }
  public Insets insets() {
    // top, left, bottom, right
    return new Insets(0, 0, 0, 0);
  }
}
class StackPanel extends Panel {
  private Label title;
  private StackMemoryViewWithTitles memoryView = new StackMemoryViewWithTitles();
  StackPanel() {
    setLayout(new BorderLayout());
    title = new Label("Stack", Label.CENTER);
    title.setFont(new Font("Helvetica", Font.BOLD, 11));
    add("North", title);
    add("Center", memoryView);
  }
  public StackMemoryView getMemoryViewReference() {
    return memoryView.getMemoryViewReference();
  }
  public Insets insets() {
    return new Insets(5, 5, 5, 5);
  }
}
class StringTable {
  public final static String appletTitle = "CIRCLE OF SQUARES";
  public final static String step = "Step";
  public final static String reset = "Reset";
  public final static String operand = "operand";
  public final static String execEnv = "exec env";
  public final static String localVars = "local vars";
  public final static String varsPointer = "vars >";
  public final static String framePointer = "frame >";
  public final static String optopPointer = "optop >";
  public final static String address = "address";
  public final static String bytecodes = "bytecodes";
  public final static String mnemonics = "mnemonics";
  public final static String hexValue = "hex value";
  public final static String value = "value";
  public final static String Registers = "Registers";
  public final static String pc = "pc";
  public final static String optop = "optop";
  public final static String frame = "frame";
  public final static String vars = "vars";
  public final static String bipushText = "bipush will expand the next byte to an int and push it onto the stack.";
  public final static String fconst_0Text = "fconst_0 will push float 0.0 onto the stack.";
  public final static String fconst_2Text = "fconst_2 will push float 2.0 onto the stack.";
  public final static String fload_0Text = "fload_0 will push the float at local variable 0 onto the stack.";
  public final static String fmulText = "fmul will pop two floats, multiply them, and push the result.";
  public final static String fstore_0Text = "fstore_0 will pop the float off the top of the stack and store it in local variable 0.";
  public final static String fsubText = "fsub will pop two floats, subtract them, and push the result.";
  public final static String gotoText = "goto will cause a jump to the specified offset.";
  public final static String iaddText = "iadd will pop the top two integers off the stack, add them, and push the result back onto the stack.";
  public final static String iconst_m1Text = "iconst_m1 will push -1 onto the stack.";
  public final static String iconst_0Text = "iconst_0 will push 0 onto the stack.";
  public final static String iconst_1Text = "iconst_1 will push 1 onto the stack.";
  public final static String iconst_2Text = "iconst_2 will push 2 onto the stack.";
  public final static String iincText = "iinc will increment the specified local variable by the specified amount.";
  public final static String iload_0Text = "iload_0 will push the integer at local variable 0 onto the stack.";
  public final static String iload_1Text = "iload_1 will push the integer at local variable 1 onto the stack.";
  public final static String imulText = "imul will pop two integers, multiply them, and push the result.";
  public final static String int2byteText = "int2byte will convert the topmost int on the stack to a value valid for the byte type.";
  public final static String istore_0Text = "istore_0 will pop the integer off the top of the stack and store it in local variable 0.";
  public final static String istore_1Text = "istore_1 will pop the integer off the top of the stack and store it in local variable 1.";
}
class ThreeParts extends Panel {
  private RegisterPanel registers;
  private TwoParts twoParts;
  ThreeParts(int methodAreaMemorySectionSize) {
    setLayout(new BorderLayout(5, 5));
    registers = new RegisterPanel();
    twoParts = new TwoParts(methodAreaMemorySectionSize);
    add("North", registers);
    add("Center", twoParts);
  }
  StackMemoryView getStackMemoryViewReference() {
    return twoParts.getStackMemoryViewReference();
  }
  MemoryView getMethodAreaMemoryViewReference() {
    return twoParts.getMethodAreaMemoryViewReference();
  }
  RegisterPanel getRegisterPanel() {
    return registers;
  }
}
// TwoParts is the panel that contains the Stack and Method Area panels
class TwoParts extends Panel {
  private StackPanel stack;
  private MethodAreaPanel methodArea;
  TwoParts(int methodAreaMemorySectionSize) {
    setLayout(new GridLayout(1, 2, 5, 5));
    stack = new StackPanel();
    methodArea = new MethodAreaPanel(methodAreaMemorySectionSize);
    stack.setBackground(ColorTable.stackAreaColor);
    methodArea.setBackground(ColorTable.methodAreaColor);
    add(stack);
    add(methodArea);
  }
  public StackMemoryView getStackMemoryViewReference() {
    return stack.getMemoryViewReference();
  }
  public MemoryView getMethodAreaMemoryViewReference() {
    return methodArea.getMemoryViewReference();
  }
  // top, left, bottom, right
  // Want a 10 pixel separation between the twoparts and the register panel
  // above and the control panel below.
  public Insets insets() {
    return new Insets(0, 0, 0, 0);
  }
}