protected UGenView( UGen ugen, UGenInfo ui, String name,
						   	Rectangle2D bounds, FontMetrics fm, FontMetrics fm2 )
		{
			this.ugen		= ugen;
//			this.ui			= ui;
//			this.name		= name;
			this.bounds		= bounds;
			
			inletLocations	= new Point2D[ ugen.getNumInputs() ];
			outletLocations	= new Point2D[ ugen.getNumOutputs() ];

			final GeneralPath	gp	= new GeneralPath();
			final GeneralPath	gp2 = new GeneralPath();
			final Area			a	= new Area();
			double				x, x2, dx, y, y2, h;
			int					r, g, b;
			UGenInput			inp;
			String				str;
			
			if( ugen.getRate() == kScalarRate ) {
				r	= 0xC0;
				g	= 0xC0;
				b	= 0xC0;
			} else if( ugen.getRate() == kControlRate ) {
				r	= 0x80;
				g	= 0x80;
				b	= 0xC0;
			} else if( ugen.getRate() == kAudioRate ) {
				r	= 0xC0;
				g	= 0x80;
				b	= 0x80;
			} else if( ugen.getRate() == kDemandRate ) {
				r	= 0x80;
				g	= 0xC0;
				b	= 0x80;
			} else {
				System.err.println( "Illegal rate : " + ugen.getRate() );
				r	= 0xC0;
				g	= 0xC0;
				b	= 0xC0;
			}

			pntBackground	= new Color( r, g, b );
			pntBorder		= new Color( r >> 1, g >> 1, b >> 1 );
			pntLabel		= new Color( r >> 2, g >> 2, b >> 2 );

			pntBackgroundS	= new Color( r >> 1, g >> 1, b >> 1 );
			pntBorderS		= new Color( r >> 2, g >> 2, b >> 2 );
			pntLabelS		= Color.white;

			pntBackgroundD	= new Color( r, g, b, 0x80 );
			pntBorderD		= new Color( r >> 1, g >> 1, b >> 1, 0x80 );
			pntLabelD		= new Color( r >> 2, g >> 2, b >> 2, 0x80 );
				
			// inlets
//			x	= SynthDefView.HPAD / 2 + 1 + bounds.getX();
			x	= SynthDefView.HPAD / 2 + 1;
			dx	= (bounds.getWidth() - 2 - SynthDefView.HPAD) / (ugen.getNumInputs() - 1);
//			y	= bounds.getY() + 1.0;
			y	= 1.0;
			h	= SynthDefView.VPAD / 4;
			
			for( int i = 0; i < ugen.getNumInputs(); i++ ) {
				inp = ugen.getInput( i );
				y2	= y;
				if( inp instanceof Constant ) {
					y2 -= 2 + fm.getHeight();
 					str = SynthDefDiagram.formatConst( ((Constant) inp).getValue() );
					collConsts.add( new PositionedString( str, x + 4, y2 + fm.getAscent() ));
					x2	= x + fm.stringWidth( str );
					gp2.moveTo( (float) x2, (float) y2 );
					gp2.lineTo( (float) x, (float) y2 );
					gp2.lineTo( (float) x, (float) y );
					collConstBounds.add( new Rectangle2D.Double( x, y2, x2 + 4 - x, y - y2 ));
				}
				gp.append( new Line2D.Double( x, y, x, y + h ), false );
				inletLocations[ i ] = new Point2D.Double( x, y );
				
				if( ui != null ) {
					str = ui.getArgNameForInput( ugen, i );
					if( str != null ) {
						collToolTips.add( new PositionedString( str, x + fm2.getAscent() - 4, y2 - 4 ));
						x2	= fm2.stringWidth( str ) + 8;
//						a.add( new Area( new Rectangle2D.Double( x - 2, y2 - x2 - 2, fm2.getHeight(), x2 )));
						a.add( new Area( new RoundRectangle2D.Double( x - 2.5, y2 - x2 - 2, fm2.getHeight(), x2, 6, 6 )));
					}
				}
				
				x += dx;
			}

			// outlets
//			x	= SynthDefView.HPAD / 2 + 1 + bounds.getX();
			x	= SynthDefView.HPAD / 2 + 1;
			dx	= (bounds.getWidth() - 2 - SynthDefView.HPAD) / (ugen.getNumOutputs() - 1);
//			y	= bounds.getY() + bounds.getHeight() - 1;
			y	= bounds.getHeight() - 1;
			
			for( int i = 0; i < ugen.getNumOutputs(); i++ ) {
				gp.append( new Line2D.Double( x, y - h, x, y ), false );
				outletLocations[ i ] = new Point2D.Double( x, y );
				x += dx;
			}

			shpCons		= gp;
			shpConsts	= gp2;
			shpToolTips	= a;
//			label		= new PositionedString( ugen.getName(), SynthDefView.HPAD / 2 + bounds.getX(),
//																SynthDefView.VPAD / 2 + bounds.getY() + fm.getAscent() );
			label		= new PositionedString( name, SynthDefView.HPAD / 2,
													  SynthDefView.VPAD / 2 + fm.getAscent() );
			
			shpContainer = new Rectangle2D.Double( 0.0, 0.0, bounds.getWidth(), bounds.getHeight() );
			
//			System.err.println( "# consts : " +collConsts.size() );
		}