setSize(w, h);
	public BlockDiagramView(int w, int h, BlockDiagramModel blockModel)	{		super(w, h, null, null);		this.model = blockModel;		this.model.addListener(new PropertyChangeListener()			{				public void propertyChange(PropertyChangeEvent evt)				{					if ( BlockDiagramModel.RENDER_CALL_PROPERTY.equals(evt.getPropertyName()) ||						  BlockDiagramModel.NUM_LEVELS_PROPERTY.equals(evt.getPropertyName()) )					{						generateLists = true;						repaint = true;						checkUpdate();					}					else /* if ( BlockDiagramModel.SHIFT_HORIZONTAL_PROPERTY.equals(evt.getPropertyName()) ||								 BlockDiagramModel.SHIFT_VERTICAL_PROPERTY.equals(evt.getPropertyName()) ||								 BlockDiagramModel.EYE_POSITION_PROPERTY.equals(evt.getPropertyName()) ||								 BlockDiagramModel.MOUSEOVER_CALL_PROPERTY.equals(evt.getPropertyName()) ||								 BlockDiagramModel.SELECTED_CALL_PROPERTY.equals(evt.getPropertyName()) ) */					{						repaint = true;						checkUpdate();					}				}			});				addKeyListener(new KeyAdapter()			{				public void keyPressed(KeyEvent e)				{					beginUpdate();					try					{						// System.out.println(e);						switch ( e.getKeyChar() )						{						case '+':							model.addLevel();							break;						case '-':							model.removeLevel();							break;						case 'r':							model.getRootRenderState().setRenderCall(model.getCallGraph());							break;						case 'p':							model.getRootRenderState().setRenderCallToParent();							break;						}						switch ( e.getKeyCode() )						{						case KeyEvent.VK_UP:							model.shiftVertical(true);							break;						case KeyEvent.VK_DOWN:							model.shiftVertical(false);							break;						case KeyEvent.VK_RIGHT:							model.shiftHorizontal(true);							break;						case KeyEvent.VK_LEFT:							model.shiftHorizontal(false);							break;						}					}					finally					{						endUpdate();					}				}			});				addMouseListener(new MouseAdapter()			{				public void mouseClicked(MouseEvent e)				{					beginUpdate();					try					{						// System.out.println(e);						if ( e.getModifiers() == MouseEvent.BUTTON1_MASK )						{							Call selectedCall = pick(e.getPoint());							model.setMouseOverCall(selectedCall);							model.setSelectedCall(selectedCall);							if ( selectedCall != null && e.getClickCount() == 2 )							{								model.getRootRenderState().setRenderCall(selectedCall);							}						}					}					finally					{												endUpdate();					}				}				public void mousePressed(MouseEvent e)				{					// System.out.println(e);					if ( e.getClickCount() == 1 && e.getModifiers() == MouseEvent.BUTTON1_MASK )					{						mouseClickPoint = e.getPoint();						mouseClickLocation = (EyeLocation)model.getEye().clone();						renderMode = BlockRenderer.RENDER_WIREFRAME;					}				}				public void mouseReleased(MouseEvent e)				{					renderMode = BlockRenderer.RENDER_SOLID;					mouseClickPoint = null;					BlockDiagramView.this.repaint();				}			});		addMouseMotionListener(new MouseMotionAdapter()			{				public void mouseMoved(MouseEvent e)				{					try					{						beginUpdate();												Call mouseOverCall = pick(e.getPoint());						model.setMouseOverCall(mouseOverCall);					}					finally					{						endUpdate();					}				}				public void mouseDragged(MouseEvent e)				{					beginUpdate();					// System.out.println(e);					if ( mouseClickPoint != null )					{						Point dragToPoint = e.getPoint();						int dx = dragToPoint.x - mouseClickPoint.x;						int dy = dragToPoint.y - mouseClickPoint.y;						double width = getSize().getWidth();						double height = getSize().getHeight();						double xFraction = -dx / width / 2 / DRAG_ROTATE_FACTOR;						double yFraction = dy / height / 2 / DRAG_ROTATE_FACTOR;						model.moveEye(xFraction, yFraction);					}					endUpdate();				}			});	}