package foggp_passepartoutj.ui; import foggp_passepartoutj.shapes.ShapeManager; import javax.swing.*; import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; /** * DrawingProgramUI - the class that implements the User Interface for this application * @author: hornick */ public class DrawingProgramUI extends JFrame { private static final long serialVersionUID = -4572711887084031106L; // private instance data members private java.awt.Container contentPane; // the drawing "canvas" private JCheckBoxMenuItem jmiLabelShape; // Label menu item private JCheckBoxMenuItem jmiEnableOutlines; // Label menu item private ShapeManager shapeManager; /** * Default constructor; builds the UI */ public DrawingProgramUI() { setTitle("SE2811 Decorated Shapes"); // initial title // tell the JFrame to dispose itself when the "close" button // in the titlebar is pressed setDefaultCloseOperation(EXIT_ON_CLOSE); setResizable( true ); contentPane = getContentPane(); // drawable region; the "canvas" contentPane.setLayout(null); setSize(600, 300); // window size = initial window size setLocation( 10, 10 ); // window pos = initial window location contentPane.setBackground(Color.BLACK); MouseEventHandler mouseHandler = new MouseEventHandler(); // create an event handler contentPane.addMouseListener( mouseHandler ); // use it to listen to MouseEvents contentPane.addMouseMotionListener( mouseHandler ); // and use it to listen to MouseMotionEvents ActionEventHandler actionHandler = new ActionEventHandler(); buildMenus(actionHandler); setVisible(true); repaint(); // No more UI calls should be made on the main thread anymore, // now that the UI is "realized". } /* * Create the menus */ private void buildMenus(ActionEventHandler ah) { //Menu Bar JMenuBar menuBar = new JMenuBar(); setJMenuBar(menuBar); //Shapes Menu JMenu shapesMenu = new JMenu("Shapes"); JRadioButtonMenuItem jmiEllipse = new JRadioButtonMenuItem("Ellipse"); jmiEllipse.setActionCommand("Ellipse"); jmiEllipse.addActionListener(ah); shapesMenu.add(jmiEllipse); JRadioButtonMenuItem jmiRect = new JRadioButtonMenuItem("Rectangle"); jmiRect.setActionCommand("Rectangle"); jmiRect.addActionListener(ah); jmiRect.setSelected(true); shapesMenu.add(jmiRect); // This group is used to make the selected shapes mutually exclusive ButtonGroup shapeSelectorGroup = new ButtonGroup(); shapeSelectorGroup.add(jmiEllipse); shapeSelectorGroup.add(jmiRect); menuBar.add(shapesMenu); //Options Menu JMenu optionsMenu = new JMenu("Options"); JMenuItem jmiOutlineColor = new JMenuItem("Outline Color"); jmiOutlineColor.setActionCommand("Outline"); jmiOutlineColor.addActionListener(ah); optionsMenu.add(jmiOutlineColor); JMenuItem jmiFillColor = new JMenuItem("Fill Color"); jmiFillColor.setActionCommand("Fill"); jmiFillColor.addActionListener(ah); optionsMenu.add(jmiFillColor); jmiLabelShape = new JCheckBoxMenuItem("Label Shape"); jmiLabelShape.setActionCommand("Label"); jmiLabelShape.addActionListener(ah); jmiLabelShape.setSelected(false); optionsMenu.add(jmiLabelShape); jmiEnableOutlines = new JCheckBoxMenuItem("Enable outlines"); jmiEnableOutlines.setActionCommand("Outlines"); jmiEnableOutlines.addActionListener(ah); jmiEnableOutlines.setSelected(false); optionsMenu.add(jmiEnableOutlines); menuBar.add(optionsMenu); } /** * paint - override of the super class paint() method. This is how paint * message handling is done, rather than with explicit action handlers. * Overriding the super class paint() method gives us the opportunity to * implement custom painting. * * Never call this method directly. * * @see java.awt.Component#paint(java.awt.Graphics) * @param g graphics context */ @Override public void paint(Graphics g){ super.paint(g); // invokes default painting for JFrame; must have this! // paint on the canvas rather than the JFrame Graphics cg = contentPane.getGraphics(); contentPane.setBackground(Color.BLACK); // TODO: Draw all the shapes } /* * Handle the mouse "click-drag-release" action. This means * to create a new shape using the currently-selected menu options. * @param start starting point for the new shape * @param end ending point for the new shape */ private void handleMouseAction( Point start, Point end ) { // TODO: Call the ShapeManager's createNewShape() method to add a shape to it's collection // NOTE: The Points object references passed as arguments to this method are owned by // the MouseEventHandler and will mutate during subsequent handling of mouse events. Be // certain to make copies of these Point objects before supplying them to ShapeManager. repaint(); // force a repaint of the window; causes paint() to be called } /* * Post a dialog allowing the user to select a color * @param title dialog title * @param originalColor current color * @return new color, or originalColor if Cancel is pressed */ private Color handleColorSelect(String title, Color originalColor) { Color newColor = JColorChooser.showDialog(this, title, originalColor ); if( newColor != null ) // if Cancel was not pressed return newColor; else return originalColor; } /* * ActionEvent handler delegates actual menu command processing here * @param cmd the ActionCommand string passed to the ActionEvent */ private void handleCommands( String cmd ) { // TODO: Eliminate these local variables if/when they are no longer unused. Color oldColor = Color.RED; boolean isSelected = false; if( cmd.equals("Outline") ) { // option to create outlined shapes has been selected // TODO: Get the current outline color selection from ShapeManager Color newColor = handleColorSelect("Select the outline color", oldColor); // TODO: Set the new outline color selection in ShapeManager } else if( cmd.equals("Fill") ) { // option to change fill color has been selected // TODO: Get the current fill color selection from ShapeManager Color newColor = handleColorSelect("Select the fill color", oldColor); // TODO: Set the current fill color selection in ShapeManager } else if( cmd.equals("Label") ) { // option to create labeled shapes has been selected // TODO: Get the current label flag status from ShapeManager jmiLabelShape.setSelected(isSelected); // TODO: Set the current label flag status in ShapeManager } else if( cmd.equals("Outlines") ) { // option to create labeled shapes has been selected // TODO: Get the current outline status from ShapeManager jmiEnableOutlines.setSelected(isSelected); // TODO: Set the current outline status in ShapeManager } else if( cmd.equals("Ellipse") ) { // subsequently created shapes will be Ellipses // TODO: Set the current primitive shape selection in ShapeManager } else if( cmd.equals("Rectangle") ) { // subsequently created shapes will be Rectangles // TODO: Set the current primitive shape selection in ShapeManager } System.out.println("DEBUG: DrawingProgramUI.handleCOma... attempting to repaint"); repaint(); // Menu messes up the picture... } /* **************************************************************************************** * Action event handler for the GraphicsShapesUI outer class * @version 1.0 * @updated 19-Jan-2009 8:47:57 AM */ private class ActionEventHandler implements ActionListener { @Override public void actionPerformed(ActionEvent e) { DrawingProgramUI.this.handleCommands( e.getActionCommand() ); } } // end ActionEventHandler inner class /* *************************************************************************************** * Mouse event handler for the GraphicsShapesUI outer class * @version 1.0 * @updated 01-May-2006 8:47:57 AM */ private class MouseEventHandler extends MouseAdapter{ private Point start; // starting coordinates for Shape, set upon mouse press private Point end; // ending coordinates for Shape, set upon mouse release // constructor; initializes the Points public MouseEventHandler(){ start = new Point(); end = new Point(); } /** * Invoked when a mouse button has been pressed on a component. * This indicates the starting location of a new shape that will * be created when the mouse is released. * * @param e MouseEvent info (location of the mouse) */ @Override public void mousePressed(MouseEvent e){ start.x = e.getX(); start.y = e.getY(); end.x = e.getX(); end.y = e.getY(); } /** * Invoked when a mouse button has been released on a component. * This indicates the ending location of the new shape that was * initiated when the mouse button was first pressed. * @param e MouseEvent info (location of the mouse) */ @Override public void mouseReleased(MouseEvent e){ end.x = e.getX(); end.y = e.getY(); handleMouseAction( start, end ); } /** * Invoked when a mouse is incrementally moved with the button down * @param e MouseEvent info (location of the mouse) */ @Override public void mouseDragged(MouseEvent e) { Graphics g = contentPane.getGraphics(); g.setXORMode(Color.GRAY); g.drawRect(Math.min(start.x, end.x), Math.min(start.y, end.y), Math.abs(end.x-start.x),Math.abs(end.y-start.y)); end.x = e.getX(); end.y = e.getY(); g.drawRect(Math.min(start.x, end.x), Math.min(start.y, end.y), Math.abs(end.x-start.x),Math.abs(end.y-start.y)); } } // end MouseEventHandler inner class } //end DrawingProgramUI class