analogapplet.java

来自「Zword公司的Rabbit2000系列相关文件」· Java 代码 · 共 858 行 · 第 1/2 页

JAVA
858
字号
	 *  along the bottom of the "value area".  The 90 deg corner
	 *  is in the lower-left corner.
	 */
	{
	    int[]    xp = new int[4];
	    int[]    yp = new int[4];

	    xp[0] = INSET;		yp[0] = INSET;
	    xp[1] = INSET;		yp[1] = d.height-INSET;
	    xp[2] = xoff + INSET;	yp[2] = d.height-INSET;
	    xp[3] = INSET;		yp[3] = INSET;

	    g.setColor( temp );
	    g.fillPolygon( xp, yp, 4 );
	}

	/*  Once the interior is done, draw a border.  Makes the value
	 *  bar look neater if container drawn later.
	 */
	g.setColor( Color.black );
	g.drawRect( INSET, INSET, d.width-2*INSET, d.height-2*INSET );

	if(true) {
	    g.drawString( " ("+ xoff +", "+ temp +") ",
		      (int) (d.width * 0.3), (int)(d.height * 0.75) );
	}

    }   /* end paint() */

    /* ---------------------------------------------------------- */    

    AnalogApplet		myOwner;

    /**	Current value in display.  Should be <tt>&lt;=</tt> <code>myMax</code>.
     */
    float			myValue;

    /**	Maximum value we can display. Helps code with scaling.
     *	Code will clip if <code>myValue</code> is too high.
     */
    float			myMax;

}   /* end class ValueDisplay */

/* ============================================================= */
/* ============================================================= */


/**
 *	Object to communicate with a remote Rabbit target.
 *	This implementation uses TCP, so after init'ing, the application
 *	calls #hookupTCP() to get us there.
 *	<br> If an error occurs, there is no &quot;status&quot; a client
 *	can query to... (sigh)
 */
class RabbitNetworkClient
{
    /** (empty) */
    public void init()
    {
    }

    /**
     *	Perform cleanup, including closing network connection.
     *	First closes the data reader/writer buffered streams, then
     *	closes the socket.
     */
    public void destroy()
    {
	try {
	    myFromServer.close();
	} catch( java.io.IOException e ) { }

	myToServer.close();

	try {
	    mySock.close();
	} catch( java.io.IOException e ) { }


    }   /* end destroy() */

    /**
     *	Connect to remote system using TCP port.  Catches most exceptions.
     *	@param	serverHost	Passed to "new Socket()" as host parameter.
     *	@param	port 		Passed to "new Socket()" as IP port number.
     *	@param	owner		Object with outMessage() and outStatus().
     *	@return	<code>TRUE</code> if TCP allows the connection, ie there was
     *			a listen waiting for us.
     *		<code>FALSE</code> if can't connect, ie host unknown, no
     *			server waiting for us, or can't write to socket.
     */
    public synchronized boolean
	hookupTCP( String serverHost, int port, AnalogApplet owner )
    {
	myOwner = owner;
	if( serverHost.equals("") ) {
	    serverHost = "localhost";
	}
	if( null == serverHost ) {
	    serverHost = "NULL";
	}
	myOwner.outMessage( " on " + serverHost + " @ " +
			    Integer.toString( port ) );

	/*  Open up a socket to BL2000 server: */
	try {
	    mySock = new Socket( serverHost, port );
	    myFromServer = new BufferedReader( new InputStreamReader(mySock.getInputStream() ));
	    myToServer = new PrintWriter( new OutputStreamWriter(mySock.getOutputStream() ));
	} catch( java.net.UnknownHostException e ) {
	    owner.showStatus( "ERROR: Can't resolve hostname" );
	    return false;
	} catch( java.io.IOException e ) {
	    owner.showStatus( "ERROR: can't read/write server." );
	    return false;
	}

	/*  Oddly, these two methods don't throw exceptions.. */
	myToServer.println( "PING" );
	myToServer.flush();

	/*  We're connected and ready. */
	return true;
    }   /* end hookupTCP() */

    /* ---------------------------------------------------------- */

    /**
     *	Worker method to send a &quot;DAC update command&quot; to remote target.
     *	Assumes both parameters have already been range checked.
     *	Method formats them and passes string to remote.
     *	Does <b>not</b> wait for response.
     *	@param	channel	DAC channel to affect.
     *	@param	value	Voltage to set on DAC channel.
     *	@see	ValueListenerBoardUpdater#updateBoard()
     */
    public synchronized void
	updateServer( int channel, float value )
    {
	myToServer.println( "SETDAC "+ channel +" "+ value );
	myToServer.flush();

	String   mesg = null;
	try {
	    if( myFromServer.ready() ) {
		mesg = myFromServer.readLine();
		if( mesg.startsWith( "ERR" ) ) {
		    myOwner.outStatus( mesg );
		} else {
		    myOwner.showStatus( "["+ mesg +"]" );
		}
	    }
	} catch( java.io.IOException e ) {
	    myOwner.showStatus( "update err: " + e );
	}

    }   /* end updateServer() */

    /* ---------------------------------------------------------- */

    AnalogApplet	myOwner;

    /**  Basic socket to remote target. */
    protected Socket		mySock;

    /**  Data from target arrives here. */
    protected BufferedReader	myFromServer;

    /**  Send commands to target here. */
    protected PrintWriter 	myToServer;

}   /* end class RabbitNetworkClient */


/* ============================================================= */
/* ============================================================= */

/**
 *	A floating-point version of Java 1.1 class AdjustmentEvent.
 *	That version holds just an integer.  We require floating-point
 *	to track voltage.
 *	@see	java.awt.event.AdjustmentEvent
 */
class  FloatingPointAdjustmentEvent extends java.awt.AWTEvent
{
    public FloatingPointAdjustmentEvent( Adjustable aSource, int aId,
					 float aValue )
    {
	super( aSource, aId );
	value = aValue;
	source = aSource;
    }

    /**
     *	Sets value in event.
     *	@param	aValue	Floating-point value.
     */
    public void setValue( float aValue )
    {
	value = aValue;
    }

    /**
     *	Get floating-point value in event.
     *	@return	float-point value stored in event.
     */
    public float getValue()
    {
	return( value );
    }

    /**
     *	Get adjusting source object.
     *	@return	Source object that created the event.
     */
    public Object getSource()
    {
	return( source );
    }

    Adjustable	source;
    float	value;

}   /* end class FloatingPointAdjustmentEvent */


abstract interface FloatingPointAdjustmentListener
    extends java.util.EventListener
{
    public abstract void valueUpdated( FloatingPointAdjustmentEvent e );
}   /* end class FloatingPointAdjustmentListener */


/**
 *	Listens to notifications from the target board and calls
 *	methods to update the GUI (which are mainly output-only 
 *	components).  Object is the only listener on the network
 *	connection.
 *	The dual of <code>ValueListenerBoardUpdater</code>.
 *	<br><b> THIS CLASS NOT FINISHED </b>
 */
class BoardListenerValueUpdater
		implements Runnable
{
    public void init()
    {
	ls = new FloatingPointAdjustmentListener[ AnalogApplet.MAX_ADC_CHANNELS ];
    }   /* end init() */

    synchronized public void addValueListener( int channel, FloatingPointAdjustmentListener l )
    {
	ls[ channel ] = l;
    }   /* end addValueListener() */

    /* ---------------------------------------------------------- */

    public void run()		/* Runnable override */
    {
    }	/* end run() */

    /* ---------------------------------------------------------- */

    FloatingPointAdjustmentListener	ls[];


}   /* end class BoardListenerValueUpdater */


/* ============================================================= */
/* ============================================================= */

/**
 *	Listens to GUI components.  When the user changes their value,
 *	sends a command via  <code>RabbitNetworkClient</code>
 *	object to have the target board change its outputs.
 *	The dual of BoardListenerValueUpdater.
 */
class ValueListenerBoardUpdater
		implements AdjustmentListener, ItemListener
{
    public void init()
    {
	out_sink = null;
	bars = new Component[10];
    }   /* end init() */

    /**
     *	Adds new input scrollbar component.  Enroll ourselves as listener
     *	when scrollbar gets frobbed by the user.
     *	Can have at most one scrollbar per channel.  Any previous
     *	scrollbar is disconnected.
     *	@param	guiScrollbar	Scrollbar element of DAC control.
     *	@param	index		Which channel scrollbar affects.
     */
    public void addInputComponent( Scrollbar guiScrollbar, int index )
    {
	if( index < bars.length ) {
	    /* XXX - if( bars[index] != NULL ) { bars[index].removeListener(this); } */
	    bars[ index ] = guiScrollbar;
	    guiScrollbar.addAdjustmentListener( this );
	} else {
	    System.out.println( "bars.add["+index+"] out of range." );
	}
    }

    /**
     *	Some client has already opened the network connection to the remote
     *	Rabbit target board.  Cache a copy.
     *	@param	netConn	Opened connection to remote target.
     */
    public void setConnection( RabbitNetworkClient netConn )
    {
	myConnection = netConn;
    }

    /**
     *	Some client informs us of place to output DEBUG commands to.
     *	@param	outs	Data output label (for debug mostly).
     */
    public void setOutput( Label outs )
    {
	out_sink = outs;
    }

    /**
     *	Some client informs us of label to output DAC voltage change.
     *	@label	volts	label to format new DAC voltage to.
     */
    public void setVoltageLabel( Label volts )
    {
	out_volts = volts;
    }

    /* ---------------------------------------------------------- */

    /**
     *	Set a listener for when a A/D channel changes value.
     *	@param var Output value displayer for remote A/D channel.
     */
    public void setAnalogOutListener( ValueDisplay bar )
    {
	out_analog = bar;
    }   /* end setAnalogOutListener() */

    /**
     *	user can choose which A/D channel to view.  When a selection occurs,
     *	Java GUI informs use with a notify.
     *	<BR><B>CODE NOT IMPLEMENTED</b>
     *	@param	e	Item even from Choice component.
     */
    public void itemStateChanged( ItemEvent e )
    {
	;
    }   /* end ItemListener::itemStateChanged() */

    /* ---------------------------------------------------------- */

    /**
     *	When a slider changes the Java GUI system notifies us.
     *	All sliders <b>must</b> be pre-registered.
     *  The scrollbar value is extract and <var>#updateBoard()</var> is called.
     *	@param e Adjustment event from a registered DAC scrollbar.
     */
    public void adjustmentValueChanged(AdjustmentEvent e)
    {
	Object   src = e.getSource();
	int     j;

	for( j=bars.length ; --j >= 0 ; ) {
	    if( bars[j] == src ) {
		break;
	    }
	}

	if( j >= 0 ) {
	    Scrollbar   s = (Scrollbar) bars[j];
	    int  where = s.getValue();
	    updateBoard( j, where );
	}
    }   /* end adjustmentValueChanged() */

    /* ---------------------------------------------------------- */

    /**
     *	When a DAC slider changes, send a command to the remote to change
     *  to a new value.
     *	@param channel Which DAC channel to affect.
     *	@param value Integer in range 0 to 4096. Here it is scaled to volts and sent.
     *	@see	AnalogApplet#myMaxVolts
     *	@see	RabbitNetworkClient#updateServer
     */
    public void updateBoard( int channel, int value )
    {
	if( VLBU_DEBUG ) {
	    /*  DEBUG - Send command to server. */
	    String cmd = " set DAC " + Integer.toString(channel) + " " +
                            Integer.toString(value);
	    out_sink.setText( cmd );
	}

	/*  Since there is no direct feedback from BL2000 when DAC
	 *  changes value.  Therefore, we just assume it will track...
	 */
	float	vf = (float)(value * AnalogApplet.myMaxVolts) / 4096.0f ;
	out_volts.setText( Float.toString( vf ) );

	myConnection.updateServer( channel, vf );

    }   /* end updateBoard() */

    /* ---------------------------------------------------------- */

    /**  Scrollbars that control DAC channels on remote. Indexed by DAC channel. */
    Component	 	bars[];

    Label		out_sink;
    Label		out_volts;
    ValueDisplay	out_analog;

    /**  Active network connection to remote target. */
    RabbitNetworkClient	myConnection;

    static final boolean VLBU_DEBUG = false;

}   /* end class ValueListenerBoardUpdater */

/* eof */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?