analogapplet.java
来自「Zword公司的Rabbit2000系列相关文件」· Java 代码 · 共 858 行 · 第 1/2 页
JAVA
858 行
/** AnalogApplet.java
*
* Z-World, 2001
*
* An applet framework for control of the analog output on a BL2000.
* Uses a TCP connection back to BL2000 for control messages.
* Code tries to use java 1.1 classes. It uses the version 1.1 input
* event model.
*
* @Version 0.05
* @date May 2001
* @Author Z-World, Inc (software)
*
*/
import java.awt.*;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
import java.applet.*;
import java.net.*;
import java.io.*;
import java.util.Vector;
/**
* Applet class. Creates visual components and network connection objects
* as well. User drags the scrollbars to control the DAC outputs.
* <br> The applet appearance looks like this:
*<pre> Message Line..
* { label(0) + slider(0).. }
* { label(1) + slider(1).. }
* Status Text..
* Value Text.. </pre>
* The "Status Text" is separate from the browser status line.
*
* <P> Will not connect with session ID 0. That means server already
* has a client it is serving. Ensures Java 1.1 classes we need
* (e.g. AWT Listener) are present.
*/
public class AnalogApplet extends Applet
{
/**
* Create layout with text labels and value scrollers.
* Connects back to host establishing a command socket.
* Uses <code>this.getCodeBase().getHost()</code> to find host system.
* Will not connect with session ID 0. That means server already
* has a client it is serving.
*
* <p> Ensures Java 1.1 classes we need (AWT Listener) are present.
*/
public void init()
{
int server_tcp_port = 0;
/* Proof of geekiness: We use the GridBagLayout manager. Rows
* with text labels stretch to full width with left-side alignment.
* Rows with scrollbars and value bars have a fixed width label
* on the leftside with a full-stretch scroll "cell".
*/
myGridBag = new GridBagLayout();
presetConstraints();
/* Now pile on the "cells" */
messageLine = new Label();
myGridBag.setConstraints( messageLine, _fullWidthConstraint );
add( messageLine );
myAnalogController = new ValueListenerBoardUpdater();
myAnalogController.init();
/* Make sure classes exist before trying to use them. */
if( !checkRuntime() ) {
outMessage( "ERROR: Required Java 1.1 classes are missing!");
outStatus( "ERROR: Applet cannot continue." );
return ;
}
/** We've check that all our Java 1.1 classes exist, proceed. **/
makeControl(0);
makeControl(1);
if( SW_A_TO_D_WORKING ) {
makeValueBar(-1); // "-1" means no A/D selected.
}
statusLine = new Label();
myGridBag.setConstraints( statusLine, _fullWidthConstraint );
add( statusLine );
valueText = new Label();
myGridBag.setConstraints( valueText, _fullWidthConstraint );
add( valueText );
valueText.setText( " " );
String param = "";
try {
param = this.getParameter( "SESSION_ID" );
if( (sessID = Integer.parseInt(param)) < 0 ) {
outMessage( "ERROR: Session ID isn't valid." );
}
param = this.getParameter( "CMD_PORT" );
if( (server_tcp_port = Integer.parseInt(param)) <= 0 ) {
outMessage( "ERROR: Illegal server TCP port." );
}
param = this.getParameter( "MAX_VOLTAGE" );
if( (myMaxVolts = (new Float(param).floatValue())) <= 0.0 ) {
outMessage( "ERROR: Illegal server TCP port." );
}
} catch( NumberFormatException e ) {
/* Either SESSION_ID wasn't found or a number conversion
* occurred. Oh well, display a diagnostic.
*/
outStatus( "ERROR: Bad params ("+param+"), you need to restart." +
sessID + "/" + server_tcp_port + "/" + myMaxVolts );
return ;
}
if( sessID == 0 ) {
/* Could make a frame here, effectively creating a dialog box.
* That exercise is left to the reader... :)
*/
outMessage( "NOTICE: Analog server is busy." );
outStatus( "NOTICE: Not connecting to remote server." );
return ;
}
myAnalogController.setOutput( statusLine );
myAnalogController.setVoltageLabel( valueText );
/* Connect to Rabbit "server" */
showStatus( "Connecting..." );
myConn = new RabbitNetworkClient();
myConn.hookupTCP( this.getCodeBase().getHost(), server_tcp_port, this );
myAnalogController.setConnection( myConn );
/* Display `ready' message in browser's status line. */
showStatus( "applet ready" );
} /* end init() method */
/** Make sure network object can close and cleanup. "destory"
* called when applet no longer needed (not just hidden).
*/
public void destroy() /* override */
{
myConn.destroy();
} /* end destroy() method */
/* ---------------------------------------------------------- */
/**
* Ensure our 1.1 classes exist in the browser's Java runtime.
* Returns TRUE when life is good. Otherwise FALSE. <b>The
* application must not continue since required classes are
* missing!</b>
*
* @return <code>FALSE</code> if a Java 1.1 class is missing.
*/
private boolean checkRuntime()
{
Class gotit;
try {
gotit = Class.forName( "java.awt.AWTEvent" );
gotit = Class.forName( "java.util.EventListener" );
gotit = Class.forName( "java.awt.event.AdjustmentListener" );
}
catch( ClassNotFoundException ex ) {
return false;
}
return true;
} /* end checkRuntime() */
/* ---------------------------------------------------------- */
/**
* Returns identification string for this application.
* Includes a psuedo-version number. String viewable through browser's
* "About.." dialog, but this author can't seem to find the
* right dialog...
* @return String with program name and version number.
*/
public String getAppletInfo() /* override */
{
return "BL2000 DAC and A/D controller / Z-World / Vers 0.05" ;
}
/**
* Returns list of <tt>PARAM</tt> keys this applet understands.
*/
public String[][] getParameterInfo() /* override */
{
String[][] result = new String[3 /* =count */ ][3];
result[0][0] = "SESSION_ID";
result[0][1] = "int";
result[0][2] = "Session ID cookie to pass to remote target.";
result[1][0] = "CMD_PORT";
result[1][1] = "int";
result[1][2] = "TCP port where command interpreter is listening on host.";
result[2][0] = "MAX_VOLTAGE";
result[2][1] = "float";
result[2][2] = "Maximum voltage can set on DAC channel.";
return( result );
}
/* ---------------------------------------------------------- */
/**
* Display messages for human. outMessage() display above sliders.
* Usually this is system status.
*/
public void outMessage( String text )
{
messageLine.setText( text );
}
/**
* Display messages for human. outStatus() display below sliders.
* Usually this is value updates and transient information.
* @see java.applet.showStatus
*/
public void outStatus( String text )
{
statusLine.setText( text );
}
/* ---------------------------------------------------------- */
/** Create a scrollbar with a label to the leftside. Label is based
* on the DAC channel we're to control. Uses proper constraints.
* The slider is an input component, sending commands to remote.
*/
private void makeControl( int channel )
{
/* Scrollbar as slider with label... */
Scrollbar slider = new Scrollbar( Scrollbar.HORIZONTAL );
slider.setValues( 0, 0, MIN_DAC_STEP_VALUE, MAX_DAC_STEP_VALUE+1 );
slider.setUnitIncrement((MAX_DAC_STEP_VALUE-MIN_DAC_STEP_VALUE+1) / 8);
slider.setBlockIncrement( slider.getUnitIncrement()/2 );
Label lab = new Label( "DAC "+channel, Label.LEFT );
myGridBag.setConstraints( lab, _labelConstraint );
lab.setAlignment( Label.CENTER );
add( lab );
myGridBag.setConstraints( slider, _valueBarConstraint );
add( slider );
myAnalogController.addInputComponent( slider, channel );
} /* end makeControl() */
/** Create an output-only "value" bar with a choice component with a Choice
* component to the left-hand side.
*/
private void makeValueBar(int which)
{
Choice ch = new Choice();
int j;
ch.addItem( "none" );
for( j=0 ; j < MAX_ADC_CHANNELS ; ++j ) {
ch.addItem( "ADC "+ j );
}
myGridBag.setConstraints( ch, _labelConstraint );
add( ch );
// XXX- ch.addItemListener( myConn );
ValueDisplay vb = new ValueDisplay(this);
// XXX- myConn.setAnaOutDisplay( vb );
myGridBag.setConstraints( vb, _valueBarConstraint );
add( vb );
} /* end makeValueBar() */
/* ---------------------------------------------------------- */
/* Build three containts: _fullWidth stretches a component to fill
* a full row. _label wraps tightly around and lives in first column.
* _valueBar Lives in the second column, and stretches to fill space.
*/
private void presetConstraints()
{
setLayout( myGridBag );
_fullWidthConstraint = new GridBagConstraints();
_fullWidthConstraint.gridx = 1;
_fullWidthConstraint.gridy = GridBagConstraints.RELATIVE;
_fullWidthConstraint.gridwidth = GridBagConstraints.REMAINDER;
_fullWidthConstraint.gridheight = 1;
_fullWidthConstraint.weightx = 10.0;
_fullWidthConstraint.weighty = 1.0;
_fullWidthConstraint.fill = GridBagConstraints.BOTH;
_fullWidthConstraint.insets = new Insets( 4, 1, 4, 1 );
_labelConstraint = new GridBagConstraints();
_labelConstraint.gridx = 1;
_labelConstraint.gridy = GridBagConstraints.RELATIVE;
_labelConstraint.gridwidth = 1;
_labelConstraint.gridheight = 1;
_labelConstraint.weightx = 0.0;
_labelConstraint.weighty = 1.0;
_labelConstraint.fill = GridBagConstraints.BOTH;
_labelConstraint.insets = new Insets( 2,2,2,2 );
_valueBarConstraint = new GridBagConstraints();
_valueBarConstraint.gridx = 2;
_valueBarConstraint.gridy = GridBagConstraints.RELATIVE;
_valueBarConstraint.gridwidth = GridBagConstraints.REMAINDER;
_valueBarConstraint.gridheight = 1;
_valueBarConstraint.weightx = 10.0;
_valueBarConstraint.weighty = 1.0;
_valueBarConstraint.fill = GridBagConstraints.BOTH;
_valueBarConstraint.insets = new Insets( 4, 4, 4, 4 );
} /* end presetConstraints() */
/* ---------------------------------------------------------- */
/* If A/D code working, change this to "true" */
final static boolean SW_A_TO_D_WORKING = false;
final static int MIN_DAC_STEP_VALUE = 0;
final static int MAX_DAC_STEP_VALUE = 4095;
static float myMaxVolts;
final static int MAX_ADC_CHANNELS = 8;
/** _fullWidth stretches a component to fill a full row. */
static GridBagConstraints _fullWidthConstraint;
/** _label wraps tightly around and lives in first column. */
static GridBagConstraints _labelConstraint;
/** _valueBar Lives in the second column, and stretches to fill space. */
static GridBagConstraints _valueBarConstraint;
GridBagLayout myGridBag;
Label valueText; /* Current voltage */
Label messageLine; /* Above slider */
Label statusLine; /* Below slider */
RabbitNetworkClient myConn;
ValueListenerBoardUpdater myAnalogController;
/** Session key sent as PARAM value to this applet. */
int sessID = 0;
} /* end class AnalogApplet */
/* ============================================================= */
/* ============================================================= */
/** Some other class listens.
* Keep the <code>ValueDisplay->myValue</code> and
* <code>ValueDisplay->myMax</code> consistent.
* Call <code>ValueDisplay()->repaint()</code> when something changes.
*/
class ValueDisplay extends Label
{
/**
* Build a displaying element with some default value.
* Since we extends Label, must give it default value.
* Label text alignment is <tt>LEFT</tt>.
*/
public ValueDisplay(AnalogApplet owner)
{
super( "---", Label.LEFT );
myOwner = owner;
myValue = 2.0f;
myMax = 4.0f;
} /* end constructor */
/* ---------------------------------------------------------- */
public void paint( Graphics g ) /* override */
{
final int INSET = 1;
final int BORDER = 1;
Dimension d = getSize();
Color bgclr = getBackground();
Color fgclr = getForeground();
Color temp;
float ratio = 0.0f;
int xoff;
try {
ratio = myValue / myMax;
if( ratio > 1.0f ) { ratio = 1.0f; }
xoff = (int) (ratio * (d.width - 2 * INSET));
/* Hue: cool=160(blue), hot=0(red)
* Saturation: cool=40, hot=255.
* Value: cool=64, hot=200
*/
temp = new Color(
Color.HSBtoRGB(
(1.0f - ratio) * 0.63f,
0.156f + (ratio * 0.84F),
0.25f + (ratio * 0.75f) ) );
} catch ( RuntimeException e ) {
g.drawString( " oppss..("+ ratio +")",
(int) (d.width * 0.40), (int)(d.height * 0.75) );
return ;
}
/* Always clear our background. It would be better to
* have an offscreen area and then just blit...
*/
g.setColor( bgclr );
g.fillRect( 0, 0, d.width, d.height );
/* Form a triangle that has one edge along the left-side
* edge (top to bottom). The point of the triangle lies
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?