/** * Bandscope Receiver Applet 1.0.0 * @author Robert J Morton * @version 13 March 2002 revised 03 April 2012 * @copyright Robert J Morton (all rights reserved) */ /* This applet conforms to API 1.1 This applet gets its bandscope data via data files acquired via a web server from an RS232 port server with an AR86000 specific data handling method - all written entirely in Java. */ import javax.swing.*; // swing widgets import java.awt.*; // for graphics operations (GUI) import java.awt.image.BufferedImage; public class bs extends JPanel implements Runnable { private static final long serialVersionUID = 207L; // what the hell this is for, I don't know! private static final int AW = 545, // width of applet panel AH = 295, // height of applet panel GL = 130, // Graph Left: x-co-ordinate of left side of graph area GT = 84, // Graph Top: y-coordinate of top of scope graph GB = 180, // Graph Bottom: panel y-co-ordinate of bottom of graph area GW = 200, // width of scope panel GH = 96, // height of scope signal bar SX = 50; // x-coordinate of left side of S-Meter signal indicator bar private int XE = 549, // Horizontal extent of window and JFrame. 545 YE = 320, // Vertical extent of window and JFrame. 295 ls = 0; // load switch private boolean Init2started = false, // phase 2 of initialisation has not yet started Init2finished = false, // phase 2 of initialization not finished FTT = true; // first time through the run() loop private static final Color bg = new Color(244,244,244); // main background colour private static final Font font1 = new Font("Serif",Font.BOLD, 14), //f or Choice menus and buttons font2 = new Font("Serif",Font.PLAIN,12); // message font(?) private long si = 1000, // run loop interval interval T, // time at which to step to the next frequency Pn = 505949278; // Pn bias constant static BufferedImage IMG1 = null, // for applet background world map images IMG2 = null, // for scope area background IMG3 = null; // for frequency scale background private String cb; // code base URL private Thread TH; // ref for a separate Internet Data Transfer thread private msgpanel mp; // message panel reference private centrefreq cf; // contains centre-frequency entry field and button private updown updn; // class containing up and down frequency buttons private freqspan sp; // class containing frequency-span selector private peakhold ph; // class containing the peak hold button and label private bands bd; // band type and band selectors and their labels private update updt; // scan data update frequency and command button private imgldr il; // instance reference to the image loader private loader ld; // reference to data loader private smeter sm; // instance ref for the S-Meter class private mousefreq mf; // instance ref for the mouse-frequency class private listeningon lo; // instance ref for the listening-on class private worldmap wm; // instance ref for the applet background class public bs(int XE, int YE, int ls, String cb) { this.XE = XE; // horizontal [X] dimension of the JPanel this.YE = YE; // vertical [Y] dimension of the JPanel this.ls = ls; // Load Switch this.cb = cb; // code base (URL) of class, images and data files setBounds(0,0,XE,YE); // the JPanel fills the whole of the JFrame area setLayout(null); // JPanel has free-form layout [for graph] setFont(font1); int W = 355, H = 24; // width and height of message-panel mp = new msgpanel(bg,font2,W,H); // general message panel at bottom left add(mp); // add message panel to the JPanel mp.setBounds(10,260,W,H); // set its position and size sp = new freqspan(this,GL,GB,30); // create frequency-span selector [safe] cf = new centrefreq(this,GL,bg,font2,mp,sp); /*centre-frequency entry field and button */ bd = new bands(this,cf,sp); // band selectors [safe] cf.setBands(bd); // pass instance reference to centre-frequency class sp.setBands(bd); // pass instance reference to frequency-span class updt = new update(this, mp); /* scan data update frequency selector and command button */ updn = new updown(this); /* buttons for inching the frequency up and down [safe] */ ph = new peakhold(this, font2); // Peak Hold button and label H = 96; // height of s-meter signal bar sm = new smeter(bg,H); // S-Meter bar display add(sm); // add S-Meter panel to this JPanel sm.setBounds(50,84,20,H); // set its position and size [safe] W = 140; H = 24; // width and height of mouse frequency panel mf = new mousefreq(this,bg,font2,sp,cf,sm,W,H); add(mf); // add mouse-frequency panel to this JPanel mf.setBounds(10,10,W,H); // set its position and size [safe] W = 220; H = 24; // width, height of "listening on" frequ panel lo = new listeningon(bg,font2,mf,W,H); add(lo); // add listening-on panel to this JPanel lo.setBounds(160,10,W,H); // set its position and size [safe] bd.setLo(lo); // inform bands class of listeningon reference cf.setLo(lo); // advise centre-frequency class of reference updn.setLo(lo); // advise up/down buttons class of reference sp.setLo(lo); // advise freqspan class of reference il = new imgldr(this,mp,ls,cb); // create and start the image loader TH = new Thread(this); // create the app's run() thresd TH.start(); // and starting it running } // [returns a call to run()] /* SECOND PHASE OF INITIALISATION: This can only be done after the background image for the applet has finished downloading from the server. Since it involves the creation of a Swing JPanel, it must be executed by the Event Dispatching thread and not the local run() thread from where the process must be invoked. */ private void scheduleInit2() { Init2started = true; // show initialisation phase 2 has been scheduled try { javax.swing.SwingUtilities.invokeAndWait( new Runnable() {public void run() {init2();}} ); } catch(Exception e) { System.out.println("createGUI phase 2 didn't successfully complete"); } } private void init2() { // CREATE SCOPE DISPLAY PANEL OBJECT scope sc = new scope(IMG2,sp,bd,cf,mf,lo,GW,GH); add(sc); sc.setBounds(GL,GT,GW,GH); cf.setScope(sc); // advise centre-frequency class of reference mf.setScope(sc); // advise mouse-frequency class of reference lo.setScope(sc); // advise listening-on class of reference sp.setScope(sc); // advise freqspan class of reference // CREATE THE FREQUENCY SCALE FIGURES DISPLAY PANEL int W = 240, H = 20; // width and height of frequency scale panel freqfigs ff = new freqfigs(IMG3,cf,W,H,sp); add(ff); ff.setBounds(110,192,W,H); cf.setFreqFigs(ff); // advise centre-frequency class of reference sp.setFreqFigs(ff); // advise freqspan class instance of reference // CREATE THE SCAN DATA FILES LOADER ld = new loader(this,mp,sc,ff,updt,ls,cb,bd); updt.setLd(ld); // advise update class of loader's class instance ref bd.setLd(ld); // advise bands class of loader's class instance ref sc.setLd(ld); // advise scope class of loader's class instance ref // CREATE THE RECEIVER MODEL-SPECIFIC SCAN DATA INTERPRETER ar86000 rx = new ar86000(ld,sc,mp,sp); // Advise the following classes of receiver's class instance reference: cf.setAR86000(rx); // centre-frequency class ph.setAR86000(rx); // peak hold class sp.setAR86000(rx); // freqspan class ld.setAR86000(rx); // loader class sc.setAR86000(rx); // scope class lo.setAR86000(rx); // listening-on class // CREATE THE APPLET'S WORLD MAP BACKGROUND PANEL wm = new worldmap(IMG1,GL,GB,GT,GW,SX); add(wm); wm.setBounds(0,0,AW,AH); ld.load(0, 0); // initiate loading of the default scan data Init2finished = true; // signal that initialization phase 2 has finished } public void run() { while(TH.isAlive()) { // while this thread exists runLoop(); // time remaining in this scan interval (time-frame) long s = T - System.currentTimeMillis(); if (s < 50) s = 50; // in case host PC is too slow try { // allow external events to break the thread Thread.sleep(s); // sleep for remainder of this time frame } catch (InterruptedException e){} // finish time of next scan interval (time frame) T = System.currentTimeMillis() + si; } } private void runLoop() { if(il.awaitingImages()) return; // if still awaiting images to be loaded if(!il.imagesLoaded()) return; // media tracker not yot terminated if(!Init2finished) { // if second phase of initialization not finished if(!Init2started) // If phase 2 of initialisation has not yet started scheduleInit2(); // do it on event-dispatching thread return; // exit here until initialisation Phase 2 finished } if(ld.scanDataLoaded()) // run through the loader control loop if(FTT) { // if first time through on program start-up repaint(); // display everything on top of background image FTT = false; // this is to avoid repreated repaints } } }