/** * Bandscope Receiver Applet 1.0.0 [BANDSCOPE GRAPH AREA] * @author Robert J Morton * @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 import java.awt.image.BufferedImage; class scope extends JPanel { private static final long serialVersionUID = 214L; // what the hell this is for, I don't know! 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 bg1 = new Color(249,182,64), // bar of freq being listened on bg2 = new Color(100,200,150), // bars of all signals in the scan bg3 = new Color(210,210,128,128), // bg for extent of band in scope area 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; // reference to the receiver class object private freqspan sp; // refernce to frequency span selector private bands bd; // ref to band types and selectors class instance private centrefreq cf; // centre frequency for current band private loader ld; // reference to the loader class instance private listeningon lo; // reference to "listening on" panel instance private mousefreq mf; // reference to "mouse frequency" panel instance scope(BufferedImage i, freqspan sp, bands bd, centrefreq cf, mousefreq mf, listeningon lo, int W, int H) { img = i; // reference to scope background image this.sp = sp; // frequency span class instance reference this.bd = bd; // bands class instance reference this.cf = cf; // centre-frequency class instance reference this.mf = mf; // mouse-frequency class instance reference this.lo = lo; // listening-on class instance reference this.W = W; // width of scope panel this.H = H; // height of scope panel mW = W + 1; // to test that mouse x-coordinate is in scope area Plots = new int[W]; // to hold the graphical signal strength plots // mouse listener to listen for mouse clicks within entire app panel addMouseListener(new ml(this)); // mouse motion listener to listen for mouse movements within app panel addMouseMotionListener(new mml(this)); } void setLd(loader ld) {this.ld = ld;} void setAR86000(ar86000 rx) {this.rx = rx;} void click(int x) { // MOUSE CLICK EVENT HANDLER if(inBounds) // provided mouse is withon bandscope graph area lo.click(x); // Go tune the receiver and highlight } // the "listening on" frequency. void scamper(int x) { // EXECUTED EVERY TIME THE MOUSE MOVES if(inBounds) // provided mouse is withon bandscope graph area mf.scamper(x); // display current frequency at mouse pointer } // on the "mouse frequency" panel void mouseEntered() { // if mouse has just entered bandscope graph area inBounds = true; // set that it is within bounds of the graph area } void mouseExited() { // if mouse has just exited bandscope graph area inBounds = false; // set that it is outside bandscope graph area mf.mouseExited(); // and clear the mouse frequency panel } void atualizar() { // CALLED BY "LOADER" AND "CENTREFREQ" // 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(), // ½kHz/pixel for selected frequency 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; sbt--; sb--; // pixel distance of start of band from centre of graph s = (CF - ((bandStarts[sbt][sb]) << 1)) / kp; // pixel distance of end of band from centre of graph e = (((bandEnds[sbt][sb]) << 1 ) - CF) / kp; } else inBand = false; // else mouse is outside the band range repaint(); // shedule a repaint via event-despatching thread } public void paint(Graphics g) { // PAINT CONTENTS OF BANDSCOPE GRAPH AREA g.drawImage(img, 0, 0, this); // draw background image onto JPanel g.setColor(bg3); // background colour of valid graph area if(inBand) // if a specific band has been selected g.fillRect(100-s,0,s+e,H); // coloured background for selected band else // else no band is selected [manual mode] g.fillRect(0, 0, W, H); // coloured background for whole graph if(rx.getDataOK()) { // if valid scan data is available g.setColor(Color.blue); // set trace colour to blue bg2 if(lp == 3) // provided data download completed for(int i = 0; i < W; i++) // display vertical bars on the chart g.drawLine(i,H,i,H - Plots[i]); } g.setColor(bg4); // colour for graticule lines for(int i = 0; i < 201; i += 20) // for each frequency graduation g.drawLine(i, H, i, 0); // vertical division line in graph area // for each S-unit graduation [Smeter.length = 13] for(int i = 0; i < 97; i += 8) g.drawLine(0, i, W, i); // draw horizontal annotation mark // if currently "listening on" a particular frequency if(lo.getReceiving()) { g.setColor(bg1); // colour for the "listening on" plot g.drawLine(hS,H,hS,H-rS); // show its vertical signal bar on chart } } // HIGHLIGHT "LISTENING ON" FREQUENCY ON GRAPH void highlightSignal(int x) { 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 the x-coordinate of the inched listening frequency is still within the scope area, return true; ortherwise return false. */ if(x > -1 && x < mW) return true; 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 overridden), 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; // app that called: always the above public ml(scope ap) { // constructor for a new cat's jaw this.ap = ap; // instance reference to the 'bs' app from which it } // came. (there will only be one instance anyway). // Invoked when the mouse has been clicked on a component. public void mouseClicked(MouseEvent e) { ap.click(e.getX()); // click() is in the above class. } public void mouseEntered(MouseEvent e) { ap.mouseEntered(); // mouse has entered the bandscope graph area } public void mouseExited(MouseEvent e) { ap.mouseExited(); // mouse has moved out of the bandscope graph area } // 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; // program that called: always the above app public mml(scope ap) { // constructor for a new Choice selection event this.ap = ap; // instance reference to the 'bs' app from which it } // came. (there will only be one instance anyway). public void mouseMoved(MouseEvent e) { // The mouse has moved ap.scamper(e.getX()); // scamper() is in the above class. It does the } // donkey work of processing mouse movements. /* The following is called when the mouse has been clicked on a choice with- in JComboBox 'id'. I don't need to use it in this application program. */ public void mouseDragged(MouseEvent e){} }