import java.awt.*; import java.awt.event.*; import java.lang.*; import java.lang.Math; public class Freefallh extends java.applet.Applet implements Runnable { Canvas oscillators; Label ballHeightLabel, vZeroLabel, aGravLabel, ballHeightS, vZeroS; TextField aGrav; Button Start, Reset; Thread runner; Scrollbar ballHeightscroll, vZeroscroll; int ballHeight, vZero, ballDiameter; int[] xpos = new int[1]; double[] x = new double[1]; double g, currentV, dropTime, ballH, intcurrentV, intballH; Image offscreenImg; Graphics offscreenG; boolean startFlag; boolean pauseFlag; void buildConstraints(GridBagConstraints gbc, int gx, int gy, int gw, int gh, int wx, int wy) { gbc.gridx = gx; gbc.gridy = gy; gbc.gridwidth = gw; gbc.gridheight = gh; gbc.weightx = wx; gbc.weighty = wy; } public void init() { GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints constraints = new GridBagConstraints(); setLayout(gridbag); // ball height text buildConstraints(constraints, 0, 0, 1, 1, 20, 5); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.EAST; Label ballHeightLabel = new Label("Initial height of ball (m):", Label.CENTER); gridbag.setConstraints (ballHeightLabel, constraints); add(ballHeightLabel); // ball Height scrollbar label buildConstraints(constraints, 2, 0, 1, 1, 20, 0); constraints.fill = GridBagConstraints.HORIZONTAL; ballHeightS = new Label("4", Label.LEFT); ballHeight = 4; gridbag.setConstraints (ballHeightS, constraints); add(ballHeightS); // ball height scrollbar buildConstraints(constraints, 1, 0, 1, 1, 20, 0); constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.WEST; ballHeightscroll = new Scrollbar(Scrollbar.HORIZONTAL, 0, 0, 0, 10); ballHeightscroll.setValue (ballHeight); gridbag.setConstraints (ballHeightscroll, constraints); add(ballHeightscroll); // Initial velocity text buildConstraints(constraints, 0, 1, 1, 1, 20, 5); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.EAST; Label vZeroLabel = new Label("Initial velocity, positive down (m/s):", Label.CENTER); gridbag.setConstraints (vZeroLabel, constraints); add(vZeroLabel); // Initial velocity scrollbar label buildConstraints(constraints, 2, 1, 1, 1, 20, 0); constraints.fill = GridBagConstraints.HORIZONTAL; vZeroS = new Label("0", Label.LEFT); vZero = 0; gridbag.setConstraints (vZeroS, constraints); add(vZeroS); // Initial velocity scrollbar buildConstraints(constraints, 1, 1, 1, 1, 20, 0); constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.WEST; vZeroscroll = new Scrollbar(Scrollbar.HORIZONTAL, 0, 0, -10, 10); vZeroscroll.setValue (vZero); gridbag.setConstraints (vZeroscroll, constraints); add(vZeroscroll); // g label buildConstraints(constraints, 0, 2, 1, 1, 20, 5); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.EAST; Label labelk = new Label("Acceleration due to gravity (between 0.1 and 100 m/s^2):", Label.RIGHT); gridbag.setConstraints (labelk, constraints); add(labelk); // k textbox buildConstraints(constraints, 1, 2, 1, 1, 0, 0); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.CENTER; aGrav = new TextField("9.8", 6); g = 9.8; gridbag.setConstraints (aGrav, constraints); add(aGrav); // Start button buildConstraints(constraints, 0, 3 , 1, 1, 0, 10); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.EAST; Start = new Button(" Start "); gridbag.setConstraints (Start, constraints); add(Start); // Reset button buildConstraints(constraints, 1, 3 , 1, 1, 0, 10); constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.WEST; Reset = new Button("Reset"); gridbag.setConstraints (Reset, constraints); add(Reset); // canvas buildConstraints(constraints, 0, 4, 3, 1, 0, 80); constraints.fill = GridBagConstraints.HORIZONTAL; oscillators = new Canvas(); gridbag.setConstraints (oscillators, constraints); add(oscillators); offscreenImg = createImage(this.size().width, this.size().height); offscreenG = offscreenImg.getGraphics(); } public void start() { if (runner == null); { runner = new Thread(this); runner.start(); } } public void stop() { if (runner != null) { runner.stop(); runner = null; } } public void run() { double deltat, junk, scale, xOrigin; Double temp; deltat=0.1; ballDiameter = 15; scale = 16.0; xOrigin = 380.0; while (true) { startFlag = false; pauseFlag = false; dropTime = 0.0; intcurrentV = vZero; intballH = ballHeight; currentV = vZero; ballH = ballHeight; x[0] = xOrigin-scale*intballH-ballDiameter; xpos[0] = (int)(x[0]); temp = Double.valueOf(aGrav.getText()); g = temp.doubleValue(); if (g < 0.1) g = 0.1; if (g > 100.0) g = 100.0; while (pauseFlag) { while (startFlag) { dropTime = dropTime + deltat; ballH = intballH-dropTime*(intcurrentV+0.5*g*dropTime); x[0] = xOrigin-scale*ballH-ballDiameter; currentV = intcurrentV+g*dropTime; if (x[0]>(xOrigin-ballDiameter)) { x[0] = xOrigin-ballDiameter; currentV = Math.sqrt(intcurrentV*intcurrentV+2.0*g*intballH); dropTime = (currentV-intcurrentV)/g; ballH = 0.0; startFlag = false; pauseFlag = true; } xpos[0] = (int)(x[0]); repaint(); try { Thread.sleep(300); } catch (InterruptedException e) { } } } repaint(); try { Thread.sleep(3); } catch (InterruptedException e) { } } } public void update(Graphics g) { paint(g); } public void paint(Graphics g) { // Draw background offscreenG.setColor(Color.white); offscreenG.fillRect(0,200,400,400); // Draw mass offscreenG.setColor(Color.black); offscreenG.drawLine(50, 380, 150, 380); offscreenG.setColor(Color.blue); if (xpos[0] > 200) { offscreenG.fillOval(100,xpos[0],ballDiameter,ballDiameter); } offscreenG.drawString("Height = " + ballH + " m", 200, 260); offscreenG.drawString("Velocity = " + currentV + " m/s", 200, 280); offscreenG.drawString("Time = " + dropTime + " s", 200, 300); g.drawImage(offscreenImg,0,0,this); } public void destroy() { offscreenG.dispose(); } public boolean action (Event evt, Object arg) { if (evt.target instanceof Button) { if ((Button)evt.target == Reset) { startFlag = false; pauseFlag = false; Start.setLabel(" Start "); } else if ((Button)evt.target == Start) { if (Start.getLabel().equals(" Start ")) { startFlag = true; pauseFlag = true; Start.setLabel("Pause"); } else { startFlag = false; pauseFlag = true; Start.setLabel(" Start "); } } } else return super.action(evt, arg); return true; } public boolean handleEvent(Event evt) { if (evt.target instanceof Scrollbar) { if ((Scrollbar)evt.target == ballHeightscroll) { ballHeight = ((Scrollbar)evt.target).getValue(); ballHeightS.setText(String.valueOf(ballHeight)); } else if ((Scrollbar)evt.target == vZeroscroll) { vZero = ((Scrollbar)evt.target).getValue(); vZeroS.setText(String.valueOf(vZero)); } repaint(); } else return super.handleEvent(evt); return true; } }