/** * Bandscope Receiver Applet 1.0.0 [BANDSCOPE GRAPH AREA] * @author Robert J Morton YE572246C * @version 13 March 2002, 20 March 2012 * @copyright Robert J Morton (all rights reserved) */ import javax.swing.*; // swing widgets import java.awt.*; // for graphics operations (GUI) import java.awt.event.*; // for the new-fangled 1.1 event handling class scope extends JPanel { private static final int bandStarts[][] = { {150,500,2300,3200,3900,4750,5950,7100,9500, 11650,13600,15510,17550,21450,25670,88000,98000}, {1810,3500,7000,10100,14000,18068,21000,24890, 28000,50000,70025,144000,430000,1240000}, {515,2850,3400,4650,5450,6525,8815,10005,11175, 13200,15010,17900,21870,23200,118000,128000}, {2000,6200,8195,12330,18780,19680,22000,25010,156000} }, bandEnds[][] = { {350,1500,2498,3400,4000,4995,6200,7300,9900, 11975,13800,15600,17900,21850,26100,98000,108000}, {1850,3800,7100,10150,14350,18168,21450,24990, 29700,52000,70500,146000,440000,1250000}, {540,3150,3500,4750,5730,6765,9040,10100,11400, 13360,15100,18030,22000,23350,128000,136950}, {2850,6525,8815,13200,18900,19800,22855,25550,162050} }; private static final Color //bar of the frequency currently being listened on bg1 = new Color(249,182,64), //bars of all signal making up the scan bg2 = new Color(100,200,150), //background for extent of band within scope area bg3 = new Color(210,210,128,128), bg4 = new Color(180,180,180); // graticule colour boolean inBand = false, // true when a valid radio band is selected inBounds = false; // true when mouse is within the scope area private int W, // width of scope panel H, // height of scope signal bar Plots[], // to hold the graphical signal strength plots s, // pixel distance of start of band from centre of graph e, // pixel distance of end of band from centre of graph hS, // graph x co-ordinate of highlighted signal rS, // graph y co-ordinate of highlighted signal lp, // current loader phase number mW ; // to test for mouse x-coordinate being within the scope area private String dataMsg; // data message to be displayed in the graph area private Image img; // reference to background image for scope area private ar86000 rx; // the receiver class object private freqspan sp; // frequency span selector private bands bd; // band types and bands selectors class instance private centrefreq cf; // centre frequency for current band private loader ld; // loader class instance private listeningon lo; // "listening on" panel instance private mousefreq mf; // "mouse frequency" panel instance scope(Image i, freqspan sp, bands bd, centrefreq cf, // CONSTRUCTOR mousefreq mf, listeningon lo, int W, int H) { img = i; // reference to scope background image // Reference to classes: this.sp = sp; // frequency span this.bd = bd; // bands this.cf = cf; // centre-frequency this.mf = mf; // mouse-frequency this.lo = lo; // listening-on this.W = W; // width of scope panel this.H = H; // height of scope panel mW = W + 1; // to test for mouse x-coordinate being within scope area Plots = new int[W]; // to hold the graphical signal strength plots /* Create mouse CLICK and MOTION listeners to listen for mouse clicks and mouse movements within the entire applet panel. */ addMouseListener(new ml(this)); addMouseMotionListener(new mml(this)); } void setLd(loader ld) {this.ld = ld;} void setAR86000(ar86000 rx) {this.rx = rx;} /* MOUSE CLICK EVENT HANDLER: provided the mouse is withon the bandscope graph area, go tune the receiver and highlight the "listening on" frequency. */ void click(int x) { if(inBounds) lo.click(x); } /* EXECUTED EVERY TIME THE MOUSE MOVES: provided the mouse is within the bandscope graph area, go display the current frequency at the mouse pointer on the "mouse frequency" panel. */ void scamper(int x) { if(inBounds) mf.scamper(x); } /* If mouse has just entered the bandscope graph area, set that it is within the bounds of the graph area. */ void mouseEntered() { inBounds = true; } /* If the mouse has just exited the bandscope graph area, set that it is outside the bandscope graph area and clear the mouse frequency panel. */ void mouseExited() { inBounds = false; mf.mouseExited(); } // CALLED BY THE "LOADER" AND "CENTREFREQ" void atualizar() { // loader phase (to check that scan data is not currently being loaded) lp = ld.getLP(); int CF = cf.getCF(), // centre frequency for current band kp = sp.getKhzpixel(), // half-kHz/pixel for selected frequ span sbt = bd.getSelectedType(), // currently selected band type sb = bd.getSelectedBand(); // currently selected band within that type if(sbt > 0 && sb > 0) { // if a specific band has been selected inBand = true; // indicate that we are currently in a band sbt--; sb--; // decrement type and band numbers // get pixel distance of start of band from centre of graph s = (CF - ((bandStarts[sbt][sb]) << 1)) / kp; // get pixel distance of end of band from centre of graph e = (((bandEnds[sbt][sb]) << 1 ) - CF) / kp; } else inBand = false; // else we are not currently in a band repaint(); // shedule a repaint via the event-despatching thread } public void paint(Graphics g) { // PAINT CONTENTS OF BANDSCOPE GRAPH AREA g.drawImage(img,0,0,this); // draw the background image onto the panel g.setColor(bg3); // background colour of valid graph area /* If a specific band has been selected put in the coloured back- ground for the selected band; else no band is selected [ie we're in manual mode], so put in the coloured background for the whole graph. */ if(inBand) g.fillRect(100 - s,0,s + e,H); else g.fillRect(0,0,W,H); /* If valid scan data is available, set trace colour to blue bg2, then provided data download has completed, display the vertical bars on the chart. */ if(rx.getDataOK()) { g.setColor(Color.blue); if(lp == 3) for(int i = 0; i < W; i++) g.drawLine(i,H,i,H - Plots[i]); } g.setColor(bg4); // colour for the graticule lines for(int i = 0; i < 201; i += 20) // For each frequency graduation, draw a g.drawLine(i, H, i, 0); // vertical division line in graph area. for(int i = 0; i < 97; i += 8) // For each S-unit graduation // (Smeter.length = 13) g.drawLine(0, i, W, i); // draw a horizontal annotation mark. if(lo.getReceiving()) { // If currently "listening on" a given frequency, g.setColor(bg1); // set the colour for the "listening on" plot g.drawLine(hS,H,hS,H - rS); // display its vertical signal bar on chart } } void highlightSignal(int x) { // HIGHLIGHT THE "LISTENING ON" FREQUENCY hS = x; // graph x-co-ordinate of mouse rS = Plots[hS]; // signal strength at mouse (in pixels) atualizar(); // update the scope display } boolean withinScopeWidth(int x) { // CALLED BY 'LISTENINGON" if(x > -1 && x < mW) // If x-coordinate of inched listening frequency return true; // is still within the scope area, return true return false; // otherwise, return false } void putPlot(int i, int x) {Plots[i] = x;} int getPlot(int i) {return Plots[i];} void killPlots() { // CALLED BY 'CENTREFREQ" AND "AR86000" for(int i = 0; i < W; i++) // clear all current graph signal plots Plots[i] = 0; // by setting each one to zero } } /* NOTE: In the following classes, all the methods must appear (ie be over- ridden) even the ones that are not required, otherwise there will be a compiler error saying that the classes are not abstract. */ class ml implements MouseListener { // LISTENS FOR MOUSE CLICKS scope ap; //the application that called: always the above applet! /* Constructor for a new cat's jaw: set the reference to the instance of the 'bs' applet from which it came. There will only be one instance. */ public ml(scope ap) { this.ap = ap; } /* Invoked when the mouse has been clicked on a component. "click()" is in the above class. */ public void mouseClicked(MouseEvent e) { ap.click(e.getX()); } // mouse has entered the bandscope graph area public void mouseEntered(MouseEvent e) { ap.mouseEntered(); } // mouse has moved out of the bandscope graph area public void mouseExited(MouseEvent e) { ap.mouseExited(); } //Invoked when a mouse button has been pressed on a component. public void mousePressed(MouseEvent e) {} //Invoked when a mouse button has been released on a component. public void mouseReleased(MouseEvent e) {} } class mml implements MouseMotionListener { // LISTENS FOR MOUSE MOVEMENTS scope ap; //the application that called: always the above applet! /* Constructor for a new Choice selection event: set the reference to the instance of the 'bs' applet from which it came. (there will only be one instance anyway). */ public mml(scope ap) { this.ap = ap; } /* The mouse has moved: scamper() is in the above class. It does the donkey work of processing mouse movements. */ public void mouseMoved(MouseEvent e) { ap.scamper(e.getX()); } /* A Choice selection event has occurred from checkbox 'id'. I don't need to use this at the moment. */ public void mouseDragged(MouseEvent e) { } }