computerscience

profilesamp;po

On the tomcat drive in folder cosc210 you will find file named PainterStartup.zip.  This file contains the source code for the start of a Painter program.  In its current state, Painter can create boxes and text objects at given locations.  Both boxes and text objects can be repositioned and resized using a mouse.  The task is to add to the program the implementation for an oval, line, image, and group objects.


Instructions:


Add an oval object.  An oval is very similar in implementation as the box, except it renders an oval instead of a rectangle.  The oval can be repositioned by dragging the object to a new location.  The oval can be resized by first clicking over the oval to display grab handles and then dragging a grab handle to a new position.  The grab handles are to be rendered at the same positions as the box.  Likewise, clicking anywhere in the smallest rectangle that encloses the oval performs selection.


Add a Line object.  A Line is to be created by selecting a Line tool and then click and drag over the canvas.  The line is rendered from the point of the initial click to the mouse pointer.  On releasing the mouse the construction of the line object is completed.  A partial implementation of a PtrDrawLine object is provided.  You will need to fix the rendering, click over, and test for inside a rectangle.


A Line is selected by clicking anywhere over the line.  Right now if you click anywhere in the rectangular region hold the line, then the line is selected.   The implementation is in the isOver method.  This needs to be fixed to only select when the click is on the line.


Given below is a partial solution to determine if a mouse click position (the x and y parameters to the isOver method) is over a line:


   double ratio = (double) getDeltaY( ) / (double) getDeltaX( );

   

   if (Math.abs(((x - getX( )) * ratio) - (y - getY( ))) <= 1) {

    return true;

   }


You need to modify this code when the y to x ratio is less than -1 or greater than 1.  (hint: Inverse the roles of x and y)


The isInside method provides the implementation for determining if the line is inside a rectangular area as specified by the parameters.  This code does not work right if the ending point of the line is to the left or above the starting point.  Fix this to work in all cases.


Add an Image object.  An Image object is created by selecting an Image tool and then clicking anywhere on the canvas.  On clicking the canvas, a File Selection Dialog should be displayed.  The dialog prompts for selection of .gif and .jpg files.  On selecting a .gif or .jpg file and clicking “Open”, an Image object that renders the image of the selected file is created at the click position.  Image selection and drag behaviors are the same as a Box object. The image object additionally renders lines at the edges of the image (as done in Box).


The code for displaying a File Selection Dialog is:


        JFileChooser fileChooser = new JFileChooser();

        fileChooser.setFileFilter(new FileFilter() {

            public boolean accept(File f) {

                return f.isDirectory() || f.getName().toLowerCase().endsWith(".jpg") 

                         || f.getName().toLowerCase().endsWith(".gif");

            }


            public String getDescription() {

                return "JPG & GIF Images";

            }

        });


        if (fileChooser.showOpenDialog(editor) ==

                          JFileChooser.APPROVE_OPTION) {

            ImageIcon imageIcon = new

                          ImageIcon(fileChooser.getSelectedFile().getAbsolutePath());



           /* you will need to do stuff with your image here         */

           /* note the Graphics object has a method drawImage() */

        }


Make sure to import FileFilter from the javax.swing.filechooser.


This code goes into the Tool


The constructor of the your DrawImage object will need to pass three arguments, the x and y coordinates obtained from the MouseEvent, and the imageIcon.  The constructor should use super(x, y) and assign an instance variable the imageIcon. Furthermore call the setSize method passing the width and height obtained from the imageIcon.  


In the rendering for the DrawImage use getImage() method of the imageIcon to get the image passed to g.drawImage method.

Add a group object.  A group object represents a set of objects that have been grouped together.  A partial implementation is provided.  Your task is to fix the rendering.   The group object should draw each of the objects in the groupedObjects list.


Before drawing any object your will need to create a new graphics object that is transposed to the dimensions if the group object itself.  To do this use:


     Graphics2D g2 = (Graphics2D) g.create(getX(), getY(), getWidth(),                   

                                                                                             getHeight());


After creating the new graphics context, use scale as follows:


   g2.scale(getXScale(), getYScale());


This will insure that all objects get rendered as at the right scale when the group object itself is resized.


After drawing each of the objects in groupedObjects list, release the resources used by the created graphics object by calling dispose:


    g2.dispose();



Have the box, oval, line, and image implement the Lineable interface.  Create instance variables as needed to hold the values of the parameters.   In the drawObject method set the line width by:


   ((Graphics2D) g.setStroke(new BasicStroke(lineWidth));


Also set the color to the lineColor:


   g2.setColor(lineColor);


In the corresponding tool object (e.g., PtrDrawBoxTool for PtrDrawBox), after creating the draw object add the following calls in the object:


   box.setLineColor(editor.getLineColor()); 

   box.setLineWidth(editor.getLineWidth()); 


Have the box and oval, line implement the Colorable interface.  Create instance variables as need to hold the value of the parameter (fillColor).   Before doing any rendering of filled areas (e.g., any g.fillXXXX method)  set the graphics color to the color instance variable:


   g.setColor(fillColor);


In the corresponding tool object (e.g., PtrDrawBoxTool for PtrDrawBox), after creating the draw object add the following calls in the object:


   box.setColor(editor.getColor()); 


Warning:


Your objects may not render correctly whenever they are resized such that either the height or width is negative.  


Bonus:


Currently, if you drag the right hand side smaller than the left (likewise the bottom smaller that the top) the objects may not be displayed correctly (or even at all).  Once in the bad display state, clicking over the object no longer works.  Second, if you click in the region of overlapping object, the object on the bottom gets selected.  It should be the top object. Fix these bugs for 5 bonus points.


Fix the problem listed in the above warning.  One possible solution is to add a normalizeRect method to PtrDrawRect.  This will adjust the x, y, width, and height variables so that width and height are never negative.  For example if width is negative then change x to be the value of x plus width and then change width to be the absolute value.  Place a call to this method in the corresponding setter methods after updating the instance variables.  (note there may be problems with the grab handles).  5 points bonus.

    • 4 years ago
    • 10
    Answer(0)