/** * @file Draw3d.java * @author R Daniel Bergeron * @see DrawCanvas.java *

* This java program shows how to create a simple program that can be used * either as an applet or application and contains a Canvas for use in simple * graphics drawing. In this case, we put an applet into an ApplicFrame, then * put the canvas and a button panel into the applet. If the program is run * as an applet, we just put the canvas and buttonPanel into the applet. *

* modified by Robert S Laramee * modification date Thursday 12 Nov 98 * A new AutoRotate Menu was added * modification date Tuesday 17 Nov 98 * The Edit Mode Menu was modified to include 2 different * drawing modes: Normal (3D) and Solid Object (2D) * modification date Saturday 21 Nov 98 * A method addUserShape() was added to add user defined * solid object shapes to the shape menu * Also, a method was added to return a reference to this * application class (myApp) * modification date Wednesday 21 Nov 98 * A File menu was added. Every application needs a file * menu. */ import java.applet.Applet; import java.awt.*; // needed for both Applet and Application import java.awt.event.*; import java.util.*; /** * Draw3d class is the main class for the program */ public class Draw3d extends Applet { public static Draw3d myApp; private static boolean runAsApplet=true; // set if run as applet private static ApplicFrame appFrame; // frame if run as applic private static MenuBar appMenuBar; private static Menu appMenus[]; // array of applic menus private static PopupMenu popup; private static Menu shapeMenu; private Slider zFrontSlider; // sliders for interaction private Slider zBackSlider; private Slider xRotSlider; private Slider yRotSlider; private Slider zRotSlider; private DrawCanvas canvas; // used for drawing private Panel buttonPanel; // collects color buttons public static void main(String args[]) { runAsApplet = false; myApp = new Draw3d(); appFrame = new ApplicFrame("Draw Application", myApp); appFrame.setMenuBar( appMenuBar ); appFrame.setSize(500, 500); // define window size appFrame.show(); // Tell window mgr to display window } /** Applet methods * Normally init, start, stop, and destroy are overridden. * We'll also need to override showStatus. * --- init */ public void init() { setLayout (new BorderLayout()); } /** --- start * Note: when run as an application, this is executed as part of the * constructor for the ApplicFrame. Hence, the static variables set * in the main function have not been initialized yet, esp. appFrame. */ public void start() { int i; canvas = new DrawCanvas (); canvas.setBackground( Color.blue ); canvas.setSize(500,500); add ( canvas, BorderLayout.CENTER ); buildMenus( ); buildSliders(); } //--- stop ---------------------------------------------------- public void stop() { remove(canvas); } //--- destroy ------------------------------------------------- public void destroy() { } //--- showStatus ---------------------------------------------- // showStatus has to be overridden since the Status window is // created by the browser/appletviewer, so if run as an application // a call to showStatus would fail. Here we simply output a status // message to standard out. public void showStatus(String s) { if ( runAsApplet ) // we're an applet super.showStatus(s); else System.out.println("Status: " + s); } //--- buildSliders -------------------------------------------- // Build the sliders (scrollbars) for zFront, zBack, and x,y,z // rotations. For now this is just going to be very ugly -- just build // them all in a row at the bottom. // void buildSliders( ) { // define all 5 sliders zFrontSlider = new Slider("zFront", Scrollbar.HORIZONTAL, 0, -1, 0 ); zBackSlider = new Slider("zBack", Scrollbar.HORIZONTAL, 0, -1, -1 ); xRotSlider = new Slider("X", Scrollbar.VERTICAL, -180, 180, 0 ); yRotSlider = new Slider("Y", Scrollbar.HORIZONTAL, -180, 180, 0 ); zRotSlider = new Slider("Z", Scrollbar.VERTICAL, -180, 180, 0 ); /** * These are some unnamed inner classes: */ FloatListener zFrontListener = new FloatListener () { public void valueChanged( float f ) { zFront(f); } }; zFrontSlider.addFloatListener( zFrontListener ); FloatListener zBackListener = new FloatListener () { public void valueChanged( float f ) { zBack(f); } }; zBackSlider.addFloatListener( zBackListener ); FloatListener xRotateListener = new FloatListener () { public void valueChanged( float f ) { xRotate(f); } public void reset() { xRotateReset(); } }; xRotSlider.addFloatListener( xRotateListener ); FloatListener yRotateListener = new FloatListener () { public void valueChanged( float f ) { yRotate(f); } public void reset() { yRotateReset(); } }; yRotSlider.addFloatListener( yRotateListener ); FloatListener zRotateListener = new FloatListener () { public void valueChanged( float f ) { zRotate(f); } public void reset() { zRotateReset(); } }; zRotSlider.addFloatListener( zRotateListener ); // We'll put 2 z-sliders into one panel that will go North. Panel northPanel = new Panel(); northPanel.setLayout( new GridLayout(1,2)); northPanel.add( zFrontSlider ); northPanel.add( zBackSlider ); add (northPanel, BorderLayout.NORTH); // The Xrotation panel goes West, Yrotation South and Zrotation East Panel southPanel = new Panel(); southPanel.setLayout( new GridLayout(1,1)); southPanel.add( yRotSlider ); add (southPanel, BorderLayout.SOUTH); Panel eastPanel = new Panel(); eastPanel.setLayout( new GridLayout(1,1)); eastPanel.add( zRotSlider ); add (eastPanel, BorderLayout.EAST); Panel westPanel = new Panel(); westPanel.setLayout( new GridLayout(1,1)); westPanel.add( xRotSlider ); add (westPanel, BorderLayout.WEST); } //--- buildMenus -------------------------------------------- void buildMenus( ) { int i; final int menuCount = 6; // file, edit, color, shape, fill, autorotate appMenus = new Menu[ menuCount ]; appMenus[0] = buildFileMenu(); appMenus[1] = buildEditMenu(); appMenus[2] = buildColorMenu(); appMenus[3] = buildShapeMenu(); appMenus[4] = buildFillModeMenu(); appMenus[5] = buildAutoRotateMenu(); // added if ( runAsApplet ) // then we're an applet, make popup menu { popup = new PopupMenu( "MenuBar" ); for ( i=0; i < appMenus.length; i++ ) popup.add( appMenus[i] ); canvas.addPopup( popup ); // tell my canvas that it has popup } else { // we're an application put menus into menu bar appMenuBar = new MenuBar(); for ( i=0; i < appMenus.length; i++ ) appMenuBar.add( appMenus[i] ); } } /** * build the shape menu was modified. The HOUSE option was removed and * now solid object shapes are added dynamically */ public Menu buildShapeMenu( ) { int i,j; int numItems; // # menu items String shapeNames[] = { "Cube", "Tetrahedron" }; int shapes[] = { DrawCanvas.CUBE, DrawCanvas.TETRA, DrawCanvas.SOLID }; MenuItem shapeItems[]; shapeMenu = new Menu ( "Shapes" ); numItems = shapeNames.length; shapeItems = new MenuItem[ numItems ]; for ( i=0; i < numItems; i++ ) { shapeItems[ i ] = new MenuItem( shapeNames[ i ] ); shapeMenu.add( shapeItems[ i ]); shapeItems[ i ].addActionListener( new DrawCanvas.SetShapeAL (canvas, shapes[ i ], null )); } return shapeMenu; } /** * This was added so The Solid Object class could call the addUserShape() * method. We want the shape menu to add an item whenever a solid shape * definition is drawn. It is kind of a hack (not very graceful). */ public static Draw3d getApp() { return myApp; } /** * addUserShape adds a user defined shape to the shape menu * This is called from the Solid Object and InSerialize classes. * @param name -the name of the new shape */ public void addUserShape(String name) { // don't add a name that's already there for (int i = 0; i < shapeMenu.getItemCount(); i++) { if (shapeMenu.getItem(i).getLabel().equals(name)) { System.out.println("** Warning: shape: " + name + " already in menu."); return; } } MenuItem newItem = new MenuItem(name); shapeMenu.add( newItem ); newItem.addActionListener( new DrawCanvas.SetShapeAL (canvas, DrawCanvas.SOLID, name)); } /** * build the file menu */ Menu buildFileMenu( ) { int i; String fileNames[] = { "Open ", "Save ", "Quit "}; int fileModes[] = { DrawCanvas.OPEN, DrawCanvas.SAVE, DrawCanvas.QUIT }; MenuItem fileItems[]; Menu fileMenu = new Menu ( "File" ); fileItems = new MenuItem[ fileNames.length ]; for ( i=0; i < fileNames.length; i++ ) { fileItems[ i ] = new MenuItem( fileNames[ i ] ); fileMenu.add( fileItems[ i ]); fileItems[ i ].addActionListener( new DrawCanvas.SetFileModeAL (canvas, fileModes[ i ] )); } return fileMenu; } //---------- build the edit menu ------------------ Menu buildEditMenu( ) { int i; String editNames[] = { "Normal Drawing Mode (3D)", "New Solid Object (2D)", "Delete One Object", "Erase All", "Reset View" }; int editModes[] = { DrawCanvas.DRAWNORMAL, DrawCanvas.DRAWSOLID, DrawCanvas.DELETE_ONE, DrawCanvas.ERASE, DrawCanvas.RESETVIEW }; MenuItem editItems[]; Menu editMenu = new Menu ( "Edit" ); editItems = new MenuItem[ editNames.length ]; for ( i=0; i < editNames.length; i++ ) { editItems[ i ] = new MenuItem( editNames[ i ] ); editMenu.add( editItems[ i ]); editItems[ i ].addActionListener( new DrawCanvas.SetEditModeAL (canvas, editModes[ i ] )); } return editMenu; } //---------- buildColorMenu ------------------ Menu buildColorMenu( ) { int i; String colorNames[] = { "White", "Cyan", "Yellow", "Blue", "Red", "Green" }; Color colors[] = { Color.white, Color.cyan, Color.yellow, Color.blue, Color.red, Color.green }; MenuItem colorItems[]; Menu colorMenu = new Menu ( "Color" ); colorItems = new MenuItem[ colorNames.length ]; for ( i=0; i < colorNames.length; i++ ) { colorItems[ i ] = new MenuItem( colorNames[ i ] ); colorMenu.add( colorItems[ i ]); colorItems[ i ].addActionListener( new DrawCanvas.SetColorAL (canvas, colors[ i ] )); } return colorMenu; } //---------- buildFillModeMenu ------------------ Menu buildFillModeMenu( ) { int i; String fillModeNames[] = { "Filled ", "Hollow "}; int fillModes[] = { DrawCanvas.FILLED, DrawCanvas.HOLLOW }; MenuItem fillModeItems[]; Menu fillModeMenu = new Menu ( "FillModes" ); fillModeItems = new MenuItem[ fillModeNames.length ]; for ( i=0; i < fillModeNames.length; i++ ) { fillModeItems[ i ] = new MenuItem( fillModeNames[ i ] ); fillModeMenu.add( fillModeItems[ i ]); fillModeItems[ i ].addActionListener( new DrawCanvas.SetFillModeAL (canvas, fillModes[ i ] )); } return fillModeMenu; } /** * buildAutoRotateMenu *

* This calls a new inner action listener class of DrawCanvas, * SetAutoRotateAL */ Menu buildAutoRotateMenu( ) { int i; String rotateModeNames[] = { "AutoRotate about X axis", "AutoRotate about Y axis", "AutoRotate about Z axis", "Please Stop Rotating" }; int rotateModes[] = { DrawCanvas.ROTATEX, DrawCanvas.ROTATEY, DrawCanvas.ROTATEZ, DrawCanvas.STOP }; MenuItem rotateModeItems[]; Menu rotateModeMenu = new Menu ( "AutoRotate" ); rotateModeItems = new MenuItem[ rotateModeNames.length ]; for ( i=0; i < rotateModeNames.length; i++ ) { rotateModeItems[ i ] = new MenuItem( rotateModeNames[ i ] ); rotateModeMenu.add( rotateModeItems[ i ]); rotateModeItems[ i ].addActionListener( new DrawCanvas.SetAutoRotateAL (canvas, rotateModes[ i ] )); } return rotateModeMenu; } //-------------- zFront -------------------------------- public void zFront ( float newval ) { DrawCanvas.setzFront( newval ); // Note: setting zFront, might change zBack zBackSlider.setValue( DrawCanvas.getzBack() ); } //-------------- zBack -------------------------------- public void zBack ( float newval ) { DrawCanvas.setzBack( newval ); // Note that zBack cannot be set in front of zFront zBackSlider.setValue( DrawCanvas.getzBack() ); } //-------------- xRotate -------------------------------- public void xRotate ( float newval ) { View.rotate( "x", newval ); canvas.repaint(); } //-------------- xRotateReset -------------------------------- public void xRotateReset ( ) { View.updateScene(); xRotSlider.setValue( 0 ); } //-------------- yRotate -------------------------------- public void yRotate ( float newval ) { View.rotate( "y", newval ); canvas.repaint(); } //-------------- yRotateReset -------------------------------- public void yRotateReset ( ) { View.updateScene(); yRotSlider.setValue( 0 ); } //-------------- zRotate -------------------------------- public void zRotate ( float newval ) { View.rotate( "z", newval ); canvas.repaint(); //System.err.println("New zRotate: " + newval ); } //-------------- zRotateReset -------------------------------- public void zRotateReset ( ) { View.updateScene(); zRotSlider.setValue( 0 ); } } // end Draw3d class