import java.awt.*; import java.applet.*; import java.awt.event.*; import java.text.*; public class ReactionFrame extends Frame implements ActionListener, ItemListener { private CheckboxGroup toleranceG = new CheckboxGroup(); private Checkbox t10X = new Checkbox("10%", toleranceG, false); private Checkbox t20X = new Checkbox("20%", toleranceG, true); private Checkbox t40X = new Checkbox("40%", toleranceG, false); private Checkbox gridX = new Checkbox("Grid", null, true); private Checkbox textX = new Checkbox("Text", null, false); private Button resetB = new Button("Reset"); private Button checkB = new Button("Check Answer"); private Label leftL = new Label("Ly = 0"), rightL = new Label("Ry = 0"); DecimalFormat df = new DecimalFormat("0.00"); //text formatting for two decimal places private RandomR randomR; //create instance of RandomR class double[] loads; //array to hold loads double fRA; //holds ReactionFrame value at A double fRB; //holds ReactionFrame value at B VHead2 head; private int radius = 15; //default radius for circles public static final int CHECK = 0; public static final int TRYAGAIN = 1; private int mode = CHECK; private int score = 0, trials = 0; //keeps track of the score and trials private DrawPanel drawPanel = new DrawPanel(); private BottomPanel bottomPanel = new BottomPanel(resetB, t10X, t20X, t40X, gridX, textX); private RightPanel rightPanel = new RightPanel(checkB); private Button startButton; //button from applet public ReactionFrame(Button startButton) { this.startButton = startButton; t10X.addItemListener(this); t20X.addItemListener(this); t40X.addItemListener(this); gridX.addItemListener(this); textX.addItemListener(this); checkB.addActionListener(this); resetB.addActionListener(this); leftL.setVisible(false); rightL.setVisible(false); setLayout(new BorderLayout()); add(drawPanel, BorderLayout.CENTER); add(bottomPanel, BorderLayout.SOUTH); add(rightPanel, BorderLayout.EAST); addWindowListener(new WindowAdapter() { //make window closable public void windowClosing(WindowEvent e) { dispose(); System.exit(0); } }); setSize(600,450); //50 pixels for bottom panel setVisible(true); } //end public void init public void actionPerformed(ActionEvent e) { if (e.getSource() == checkB) { if (mode == CHECK) { checkB.setLabel("Try Again"); mode = TRYAGAIN; trials ++; drawPanel.checkAnswer(); rightPanel.repaint(); } else { drawPanel.tryAgain(); checkB.setLabel("Check Answer"); mode = CHECK; } } else if (e.getSource() == resetB) { drawPanel.tryAgain(); checkB.setLabel("Check Answer"); mode = CHECK; trials = 0; score = 0; rightPanel.repaint(); } } public void itemStateChanged(ItemEvent e) { if (e.getSource() == gridX) { drawPanel.repaint(); } else if (e.getSource() == textX) { if (textX.getState()) { leftL.setVisible(true); rightL.setVisible(true); } else { leftL.setVisible(false); rightL.setVisible(false); } drawPanel.repaint(); } else if (e.getSource() == t10X) { radius = 7; drawPanel.repaint(); } else if (e.getSource() == t20X) { radius = 15; drawPanel.repaint(); } else if (e.getSource() == t40X) { radius = 30; drawPanel.repaint(); } } //inner class public class DrawPanel extends Panel implements MouseListener, MouseMotionListener { private Point joint[]; double[] loads; private boolean leftCircle = false, rightCircle = false; private int oldLy = 0, oldRy = 0; //holds previous values public DrawPanel() { setBackground(Color.white); addMouseListener(this); addMouseMotionListener(this); //call RandomR method to read in values of loads and reactions randomR = new RandomR(); loads = randomR.getLoads(); fRA = randomR.getReactionA(); fRB = randomR.getReactionB(); setLayout(null); add(leftL); leftL.setBounds(VX(0)-35,280,60,20); add(rightL); rightL.setBounds(VX(300)-25,280,60,20); } public void paint(Graphics g) { //draw border g.drawRect(1,1,getSize().width-2, getSize().height-2); //draw grid if (gridX.getState()) { g.setColor(Color.orange); for (int i=-50; i<=350; i=i+10) { //draw vertical grid g.drawLine(VX(i),VY(-100),VX(i),VY(200)); } for (int i=-100; i<=200; i=i+10) { //draw horizontal grid g.drawLine(VX(-50),VY(i),VX(350),VY(i)); } } //end if (grid.getState()) //draw structure createJointCoord(); //read in joint coordinates int js, je; //draw truss. js = start joint num, je = end joint num g.setColor(Color.black); js = 1; je = 2; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 2; je = 3; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 3; je = 4; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 4; je = 5; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 5; je = 6; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 6; je = 7; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 7; je = 8; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 8; je = 9; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 9; je = 10; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 10; je = 11; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 11; je = 12; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 12; je = 1; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 2; je = 12; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 12; je = 3; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 11; je = 3; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 3; je = 10; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 10; je = 4; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 10; je = 5; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 9; je = 5; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 5; je = 8; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); js = 8; je = 6; g.drawLine(VX(joint[js].getX()),VY(joint[js].getY()), VX(joint[je].getX()), VY(joint[je].getY())); //draw filled circles at all joints for (int i=1; i<=12; i++) { g.fillOval(VX(joint[i].getX())-3,VY(joint[i].getY())-3,6,6); } //draw supports g.drawLine(VX(0),VY(0),VX(0)-5,VY(0)+15); //left pin g.drawLine(VX(0)-5,VY(0)+15,VX(0)+5,VY(0)+15); g.drawLine(VX(0)+5,VY(0)+15,VX(0),VY(0)); g.fillRect(VX(0)-15,VY(0)+15,30,5); g.drawOval(VX(0)+300-7,VY(0),15,15); //right roller g.fillRect(VX(0)-15+300,VY(0)+15,30,5); //draw loads int j = 1; for (int i = 50; i<=250; i=i+50) { if (loads[j] != 0.0) { g.drawLine(VX(i), VY(0),VX(i),VY(0)+(int)loads[j]); head = new VHead2(1,VX(i), VY(0),VX(i),VY(0)+(int)loads[j]); //use VHead2 class to get arrow head g.fillPolygon(head.xpoints(), head.ypoints(), head.npoints()); //draw arrowhead //draw values if textX.getState() == true if (textX.getState()) g.drawString(""+df.format(loads[j]),VX(i)-20,VY(0)+(int)loads[j]+15); } j++; } //draw reactions g.setXORMode(Color.white); g.drawLine(VX(0),VY(0),VX(0),VY(oldLy)); head = new VHead2(1,VX(0),VY(0),VX(0),VY(oldLy)); //use VHead2 class to get arrow head g.fillPolygon(head.xpoints(), head.ypoints(), head.npoints()); //draw arrowhead g.drawLine(VX(300),VY(0),VX(300),VY(oldRy)); head = new VHead2(1,VX(300),VY(0),VX(300),VY(oldRy)); //use VHead2 class to get arrow head g.fillPolygon(head.xpoints(), head.ypoints(), head.npoints()); //draw arrowhead //draw circles g.drawOval(VX( 0)- radius,VY(oldLy)- radius,radius*2,radius*2); g.drawOval(VX(300)- radius,VY(oldRy)- radius,radius*2,radius*2); if (mode == TRYAGAIN) { //draw answers g = getGraphics(); g.setColor(Color.red); g.drawLine(VX(0),VY(0),VX(0),VY((int)fRA)); head = new VHead2(1,VX(0),VY(0),VX(0),VY((int)fRA)); g.fillPolygon(head.xpoints(), head.ypoints(), head.npoints()); g.drawLine(VX(300),VY(0),VX(300),VY((int)fRB)); head = new VHead2(1,VX(300),VY(0),VX(300),VY((int)fRB)); g.fillPolygon(head.xpoints(), head.ypoints(), head.npoints()); if (textX.getState()) { g.setFont(new Font("Arial,Helvetica", Font.BOLD, 13)); g.drawString("Correct Reaction on Left Support, Ly = " + df.format(fRA),VX(25),VY(150)); g.drawString("Correct Reaction on Right Support, Ry = " + df.format(fRB),VX(25),VY(130)); } } } //end public void paint //virtual x and y coordinates public int VX(int x) { return (x+100); } public int VY(int y) { return (getSize().height - y - 125); } //returns actual coordinates, accepts virtual coordinates public int Y(int vy) { return (getSize().height - vy - 125); } public void createJointCoord() { //create joint coordinates joint = new Point[13]; joint[1] = new Point(0, 0); joint[2] = new Point(50, 0); joint[3] = new Point(100, 0); joint[4] = new Point(150, 0); joint[5] = new Point(200, 0); joint[6] = new Point(250, 0); joint[7] = new Point(300, 0); joint[8] = new Point(250,50); joint[9] = new Point(200,50); joint[10] = new Point(150,50); joint[11] = new Point(100,50); joint[12] = new Point(50, 50); } //end public void createJointCoord //MouseListener functions public void mouseReleased(MouseEvent e) { leftCircle = false; rightCircle = false; } public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mousePressed(MouseEvent e) { if (Math.sqrt( (VX(0)-e.getX())*(VX(0)-e.getX()) + (VY(oldLy)-e.getY())*(VY(oldLy)-e.getY())) < radius) leftCircle = true; if (Math.sqrt( (VX(300)-e.getX())*(VX(300)-e.getX()) + (VY(oldRy)-e.getY())*(VY(oldRy)-e.getY())) < radius) rightCircle = true; } //MouseMotionListener functions public void mouseMoved(MouseEvent e) {} public void mouseDragged(MouseEvent e) { Graphics g = getGraphics(); g.setXORMode(Color.white); if (leftCircle) { g.drawLine(VX(0),VY(0),VX(0),VY(oldLy)); //erase line head = new VHead2(1,VX(0),VY(0),VX(0),VY(oldLy)); g.fillPolygon(head.xpoints(), head.ypoints(), head.npoints()); //erase vhead g.drawOval(VX(0)- radius,VY(oldLy)- radius,radius*2,radius*2); //erase circles g.drawLine(VX(0),VY(0),VX(0),e.getY()); //draw line head = new VHead2(1,VX(0),VY(0),VX(0),e.getY()); g.fillPolygon(head.xpoints(), head.ypoints(), head.npoints()); //draw vhead g.drawOval(VX(0)-radius,e.getY()-radius,radius*2,radius*2); //draw circles oldLy = Y(e.getY()); leftL.setText("Ly = " + oldLy); } if (rightCircle) { g.drawLine(VX(300),VY(0),VX(300),VY(oldRy)); //erase line head = new VHead2(1,VX(300),VY(0),VX(300),VY(oldRy)); g.fillPolygon(head.xpoints(), head.ypoints(), head.npoints()); //erase vhead g.drawOval(VX(300)- radius,VY(oldRy)- radius,radius*2,radius*2); //erase circles g.drawLine(VX(300),VY(0),VX(300),e.getY()); //draw line head = new VHead2(1,VX(300),VY(0),VX(300),e.getY()); g.fillPolygon(head.xpoints(), head.ypoints(), head.npoints()); //draw vhead g.drawOval(VX(300)-radius,e.getY()-radius,radius*2,radius*2); //draw circles oldRy = Y(e.getY()); rightL.setText("Ry = " + oldRy); } } public void checkAnswer() { //update score if (Math.abs(fRA-oldLy) < radius) { if (t10X.getState()) score = score + 20; else if (t20X.getState()) score = score + 10; else if (t40X.getState()) score = score + 5; } if (Math.abs(fRB-oldRy) < radius) { if (t10X.getState()) score = score + 20; else if (t20X.getState()) score = score + 10; else if (t40X.getState()) score = score + 5; } if (score >= 100) { score = 0; trials = 0; } repaint(); } public void tryAgain() { //call RandomR method to read in values of loads and reactions randomR = new RandomR(); loads = randomR.getLoads(); fRA = randomR.getReactionA(); fRB = randomR.getReactionB(); oldLy = 0; oldRy = 0; leftL.setText("Ly = " + oldLy); rightL.setText("Ry = " + oldRy); repaint(); } } //end public class DrawPanel //inner class public class BottomPanel extends Panel { public BottomPanel(Button resetB, Checkbox t10X, Checkbox t20X, Checkbox t40X, Checkbox gridX, Checkbox textX) { setBackground(Color.lightGray); add(resetB); add(new Label(" Tolerance")); add(t10X); add(t20X); add(t40X); add(new Label(" ")); add(gridX); add(textX); } public void paint(Graphics g) { g.drawRect(1,1,getSize().width-2, getSize().height-2); } } //end public class BottomPanel //inner class public class RightPanel extends Panel { TopPanel topPanel; BottomPanel bottomPanel; public void repaint() { topPanel.repaint(); } public RightPanel(Button checkB) { setBackground(Color.white); topPanel = new TopPanel(); bottomPanel = new BottomPanel(checkB); setLayout(new BorderLayout()); add(topPanel, BorderLayout.CENTER); add(bottomPanel, BorderLayout.SOUTH); } //inner class public class TopPanel extends Panel { private Font f2 = new Font("Arial,Helvetica", Font.PLAIN, 9); private Font f3 = new Font("Arial,Helvetica", Font.BOLD, 12); private int xo = 37; //offset values for meter private int yo = 70; //same as xo private int width = 30; //width of meter public void paint(Graphics g) { g.drawRect(1,1,getSize().width-2, getSize().height-2); //draw text "total points" g.drawString("Total",xo-5,yo-30); g.drawString("Points",xo-5,yo-15); //draw score g.setColor(Color.orange); if (score > 20) g.setColor(Color.yellow); if (score > 50) g.setColor(Color.red); g.fillRect(xo,yo+200-score*2,width,score*2); //draw meter g.setColor(Color.black); for (int i= 0; i<200; i=i+20) { g.drawRect(xo,yo+i,width,20); } //label meter g.setFont(f2); for (int i = 0; i<=100; i=i+10) { g.drawString(""+(100-i),(xo-20),(yo+i*2+2)); } int tx = 35, ty = getSize().height-30; g.setFont(f3); g.drawString("Trials", tx,ty); g.drawString("" + trials, tx+15,ty+15); } } //end class public class TopPanel //inner class public class BottomPanel extends Panel { public BottomPanel(Button checkB) { add(checkB); } public void paint(Graphics g) { g.drawRect(1,1,getSize().width-2, getSize().height-2); } } //end class public class BottomPanel } //end public class RightPanel //overrides dispose in class java.awt.Frame public void dispose() { super.dispose(); startButton.setEnabled(true); } public static void main(String args[]) { ReactionFrame reactionFrame = new ReactionFrame(new Button("dummyButton")); } } //end public class ReactionFrame