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!

Recommended Answers

All 8 Replies

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

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?

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

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

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.

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 developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.