Hello,

In my java class we've been asked to create a painter program that allows the user to draw on the screen (as with a paintbrush). I had no trouble creating the program and having it perform up to standards with what was asked, but something that troubles me and that the teacher could not really answer for me was this: how do I manage to make the thing drawn be fluid lines instead of random dots?

The program performs great when drawing slowly, but when drawing fast, the image drawn becomes 'dotted' and has a lot of gaps. Any help scratching this itch would be greatly appreciated.

p.s. I've tried rendering off-screen first, same results. I believe the problem is the way the mouse event is handled, but I have no idea how else to handle it (app must draw when left mouse button is down and erase when right mouse button is down)

Here is the relevant part of my code:

Handling the mouse dragged event

private void formMouseDragged(java.awt.event.MouseEvent evt) 
    {                                  
       
        if (evt.isAltDown() == false && evt.isControlDown() == false && evt.isMetaDown() == false && evt.isShiftDown() == false)
        {                     
            if (pointCount < points.length)
            {
                point = new ColorPoint(getBrushSize(), getColor(), evt.getX(), evt.getY());
                points[pointCount] = point;
                pointCount++;  
                repaint();
            }
        }
        else if (evt.isMetaDown())
        {
            if (pointCount < points.length)
            {
                point = new ColorPoint(getBrushSize(), this.getBackground(), evt.getX(), evt.getY());
                points[pointCount] = point;
                pointCount++;
                repaint();
            }
        }
        
    }

My paintComponent method

public void paintComponent (java.awt.Graphics g)
    {
        
        super.paintComponent(g);
        
        for (int i = 0 ; i < pointCount ; i++)
        {
            
            g.setColor(points[i].getColor());
            g.fillOval(points[i].x, points[i].y, points[i].getBrushS(), points[i].getBrushS());
        }
         
    }

Thanks!

Re: Java Paint Program Question 80 80

I remmeber coding it 4 years back from the java book by deitel and deitel.

commented: This reply is not helpful in the least. -1
Re: Java Paint Program Question 80 80

That... doesn't really help much, but thanks anyways, I guess I'll try to see if any examples for that book are around on the 'net....

Anyone else?

Re: Java Paint Program Question 80 80

Your best bet is to construct a GeneralPath with the points from the mouse listener and use the Graphics2D.draw(Shape) method to render it. You can append to the GeneralPath as new points are added, so you don't have to even maintain a point collection at all.

Examples of this can be found here: http://java.sun.com/docs/books/tutorial/2d/geometry/arbitrary.html

Re: Java Paint Program Question 80 80

That sounds great, the only problem is that if I do it that way, the width can not be changed, and that's a necessary feature for the program

Re: Java Paint Program Question 80 80

Thank you SO MUCH!! I'll try this out tomorrow

Re: Java Paint Program Question 80 80

hi sir;
my name is sandeep . i recently cleared scjp exam . sir now i am looking to start a porject with java can you suggest me something.
and sir what was that paint program question.

and if you can give me some hint for this it will be good for me. not code but some general lines how to handle it.

Re: Java Paint Program Question 80 80

Just in case anybody wishes to know, I ended up creating an array of GeneralPaths, an array of int for brushsizes, and an array of Color for brush color, plus an extra GeneralPath outside the array to be able to draw as the user inputs.

Following are my event handlers:

private void formMouseReleased(java.awt.event.MouseEvent evt)                                   
    {                                       
        
        /*
         *This event handler is used to be able to tell when the user lets go of the mouse button, 
         *which is necessary so the image drawn has separate lines instead of one big mess of connected
         *things. The color and size of each path are finalized in this event handler.
         */
        
        if (pathCount < paths.length)
        {
            paths[pathCount] = path; //finalize the path
            if(!delete)
                pColor[pathCount] = getColor(); //Set the color if not deleting
            else if (delete)
            {
                pColor[pathCount] = this.getBackground(); //Else set the color to the background
                delete = false;
            }
            pSize[pathCount] = getBrushSize(); //Set the brush size for this path
            pathCount++;
            path = new GeneralPath(); //Reset the path
        }
        stillPressed = false; //Starts a new path next time user drags the mouse
    }                                  
       
    private void formMouseDragged(java.awt.event.MouseEvent evt) {                                  
      
        if (!evt.isAltDown() && !evt.isControlDown() && !evt.isMetaDown() && !evt.isShiftDown())
        {                     
            if (!stillPressed) //Start a new path
            {
                path.moveTo(evt.getX(), evt.getY());
                stillPressed = true;
                repaint();
            }
            else if (stillPressed) //Continues the path if user has not let go of the mouse button
            {
                path.lineTo(evt.getX(), evt.getY());
                repaint();
            }

        }
        else if (evt.isMetaDown()) //Erase stuff on screen
        {
            if (!stillPressed) //Starts a new path, this path will have the color be the same as background (see event handler above)
            {
                path.moveTo(evt.getX(), evt.getY());
                stillPressed = true;
                delete = true;
                repaint();
            }
            else if (stillPressed) //Continues same path
            {
                path.lineTo(evt.getX(), evt.getY());
                repaint();
            }
        }     
        
    }

Following is my paintComponent method:

public void paintComponent (java.awt.Graphics g)
    {
        
        super.paintComponent(g);
        
        Graphics2D g2 = (Graphics2D) g; // Necesary for the setStroke method
        
        for (int i = 0 ; i < pathCount ; i++) //Draws existing paths
        {
            stroke = new BasicStroke(pSize[i], stroke.CAP_ROUND, stroke.JOIN_ROUND);
            g.setColor(pColor[i]);
            g2.setStroke(stroke);
            g2.draw(paths[i]);
        }
        
        //The following draws the current path the user is working on
         
        stroke = new BasicStroke(getBrushSize(), stroke.CAP_ROUND, stroke.JOIN_ROUND);
        if (!delete)
            g.setColor(getColor()); //Uses user-defined color if not deleting
        else if (delete)
            g.setColor(this.getBackground()); //Uses background as color if deleting (right-click)
        g2.setStroke(stroke);
        g2.draw(path);                 
    }

Hope this helps someone

commented: Keep up good work +7
Be a part of the DaniWeb community

We're a friendly, industry-focused community of 1.19 million developers, IT pros, digital marketers, and technology enthusiasts learning and sharing knowledge.