/** Alternative Relativity: Doppler Effect Demonstrator by Robert John Morton UK-YE572246C (Belo Horizonte-MG 27 September 2006, 02 May 2012) Produced (concept to full release) in 5 afternoons. + 2 more afternoons to convert itto Swing. */ /* HTML call for this applet: */ import javax.swing.*; // library of swing widgets import java.awt.*; // for graphics operations (GUI) import java.lang.System; // to deal with foreign language options import java.awt.event.*; // for the new-fangled 1.1 event handling public class doppler extends JApplet implements Runnable { private long P = 15, // applet's prescribed cycle period (milliseconds) T = 0, // System Time at end of last cycle δT = 0, // change in System Time between last cycle and this cycle sl = 10; // required sleep time (P - δT) private int ds = 0; // default mode selection private Image H; // off-screen image private Graphics h; // graphics reference variable private volatile Thread TH; // declare a thread reference variable private wpanel wp; // instance for the wave display panel private String GS = "PGBR505949278"; // hashing constant public void init() { // INITIALIZE THE APPLET: Phase 1 of GUI build try { javax.swing.SwingUtilities.invokeAndWait( new Runnable() { public void run() { init1(); } } ); } catch(Exception e) { showStatus("couldn't create Swing GUI"); } } /* THE FIRST PHASE OF INITIALISATION: Since this involves the creation and set-up of Swing widgets, it must be done on the Event Dispatching thread. It is invoked from the applet's init() method above. */ private void init1() { //localized annotations for applet's mode selector buttons String SA[][] = { {"Mode Selector:", "Selecione Modo:"}, {" Classical Relativity", " Relatividade Classica"}, {" Alternative Relativity", " Relatividade Alternativa"} }; int ls = Integer.valueOf(getParameter("lang")).intValue(); // Put the label text for the selected language into the S[] text array. String S[] = new String[3]; for(int i = 0; i < 3; i++) S[i] = SA[i][ls]; // get applet's default mode from HTML parameter ds = Integer.valueOf(getParameter("selmode")).intValue(); boolean DS[] = {false, false}, // boolean array to represent button states DS[ds] = true; // default mode received from HTML call parameter /* Get the content pane of the JApplet and set it to allow the control panels to be laid out manually. */ Container cp = getContentPane(); cp.setLayout(null); /* Create the mode selector label, add it to the applet pane then set its position and size within the pane. */ JLabel L = new JLabel(S[0], Label.LEFT); cp.add(L); L.setBounds(0, 0, 130, 39); /* Create a checkbox group then create two mode buttons, add them to the group so that they can be used as linked radio buttons, add the buttons to the applet pane and then create event listeners for them to detect whenever each one is pressed. */ ButtonGroup G = new ButtonGroup(); JRadioButton A = new JRadioButton(S[1], DS[0]); JRadioButton B = new JRadioButton(S[2], DS[1]); G.add(A); cp.add(A); A.setBounds(130, 0, 170, 39); G.add(B); cp.add(B); B.setBounds(300, 0, 180, 39); A.addItemListener(new modebut(0, this)); B.addItemListener(new modebut(1, this)); /* Create image in which to animate the doppler waves off screen and get the image's graphics context reference. */ H = createImage(1200, 191); h = H.getGraphics(); /* Create an instance of the wave display panel, add it to the applet pane and set its position and size within the pane. */ wp = new wpanel(H, h, ds); cp.add(wp); wp.setBounds(0, 40, 500, 190); } /* Start program thread by creating the thread object and starting it running. [returns a call to run()]*/ public void start() { TH = new Thread(this); TH.start(); // Set the System Time at which the first time frame will terminate. T = System.currentTimeMillis() + P; } public void run() { while (TH != null) { //while the run() thread remains alive /* Get the time 'δT' remaining in the current time frame. If this is less than the reserve sleep time 'sl', set 'δT' to the reserve value 'sl'. Put the tread to sleep for this remaining time. */ δT = T - System.currentTimeMillis(); if(δT < sl) δT = sl; try { TH.sleep(δT); } /* If a browser event occurs while the thread is asleep, set the change flag to re-start a new traverse of the light-source. */ catch (InterruptedException e) { wp.setCF(true); } // Set the System Time at which the next time frame will terminate. T = System.currentTimeMillis() + P; wp.atualizar(); //update the waves /* repaint the entire applet (necessary for Swing) bringing the Graphics environment with it. */ repaint(); } } public void stop() { TH = null; } // kill this applet's thread // CALLED BY EVENT LISTENER CLASS BELOW void selectMode(int ds) { wave.setMode(ds); // re-initialize the static mode variable in wave.class wp.setCF(true); // set the change flag to re-start the waves wp.setDS(ds); // set new mode: 'classical' or 'alternative' wp.atualizar(); // re-initialize the display - sets up call to update() } } // LISTENS FOR EVENTS FROM THE MODE SELECTOR BUTTONS class modebut implements ItemListener { int id; // one of the above events doppler ap; // application that called: always the above applet! /* constructor for a new checkbox event: sets 'id' number of this instance of 'modebut' and the reference to this instance of the applet from which it came. (only one instance anyway). */ public modebut(int id, doppler ap) { this.id = id; this.ap = ap; } // a checkbox event has occurred from checkbox 'id' public void itemStateChanged(ItemEvent e) { switch(id) { // communicate the selection to the above applet. case 0: ap.selectMode(0); break; // "classical relativity" case 1: ap.selectMode(1); break; // "alternative relativity" } } }