1

I have written an applet in Java that allows the user to set background color, and "pen" color then click and draw in the window frame to drawn a line. I set this line by filling ovals at each x and y point of the dragging mouse. I also allows user to use the - and + keys to change the size of the line by increasing or decreasing the radius of the ovals. My issue is that there is some cause of lag in the drawing of the line. I believe it is in the mouseDrag method and the speed at which that method is executed limits how many x and y points can be attained to paint ovals on. Is there any way to alleviate this lag to allow for better lines?

import java.applet.Applet;
import java.awt.Event;
import java.awt.Color;
import java.awt.Graphics;

public class Screen extends Applet
{
    int x = -20, y = -20;
    int height = 20, width = 20;
    boolean black, blue, cyan, green, magenta, orange, pink, red, white, yellow;

    public void init()
    {
    setSize(400,400);
    setBackground(Color.white);
    }
    public void paint(Graphics g)
    {
    if (black == true)
        g.setColor(Color.BLACK);
    else if (blue == true)
        g.setColor(Color.BLUE);
    else if (cyan == true)
        g.setColor(Color.CYAN);
    else if (green == true)
        g.setColor(Color.GREEN);
    else if (magenta == true)
        g.setColor(Color.MAGENTA);
    else if (orange == true)
        g.setColor(Color.ORANGE);
    else if (pink == true)
        g.setColor(Color.PINK);
    else if (red == true)
        g.setColor(Color.RED);
    else if (white == true)
        g.setColor(Color.WHITE);
    else if (yellow == true)
        g.setColor(Color.YELLOW);

    g.fillOval(x, y, width, height);
    }
    public boolean mouseDrag(Event e, int xPos, int yPos)
    {
    x = xPos;
    y = yPos;
    paint(getGraphics());
    return true;
    }
    public boolean keyDown(Event e, int key)
    {
    black = false;
    blue = false;
    cyan = false;
    green = false;
    magenta = false;
    orange = false;
    pink = false;
    red = false;
    white = false;
    yellow = false;

    if (key == 'n')
    {
        x =-20;
        y =-20;
        update(getGraphics());
    }
    else if (key == 'x')
        black = true;
    else if (key == 'b')
        blue = true; 
    else if (key == 'c')
        cyan = true;
    else if (key == 'g')
        green = true;
    else if (key == 'm')
        magenta = true;
    else if (key == 'o')
        orange = true;
    else if (key == 'p')
        pink = true;
    else if (key == 'r')
        red = true;
    else if (key == 'w')
        white = true;
    else if (key == 'y')
        yellow = true;
    else if (key == '+')
    {
        height += 5;
        width += 5;
    }
    else if (key == '-')
    {
        height += -5;
        width += -5;
    }
    else if (key == 'X')
        setBackground(Color.BLACK);
    else if (key == 'B' )
        setBackground(Color.BLUE); 
    else if (key == 'C')
        setBackground(Color.CYAN);
    else if (key == 'G')
        setBackground(Color.GREEN);
    else if (key == 'M')
        setBackground(Color.MAGENTA);
    else if (key == 'O')
        setBackground(Color.ORANGE);
    else if (key == 'P')
        setBackground(Color.PINK);
    else if (key == 'R')
        setBackground(Color.RED);
    else if (key == 'W')
        setBackground(Color.WHITE);
    else if (key == 'Y')
        setBackground(Color.YELLOW);
    return true;
    }
}
DirtyWhite
  • 63
  • 1
  • 5

1 Answers1

1

Your painting looks questionable:

  • You're calling paint(...) directly, something that should never be done.
  • You're not calling the super.paint(...) method inside of your paint override.
  • Try minimizing your GUI and then restoring it, and tell me how much of your drawing disappears into the nothingness.

Instead you should:

  • call repaint() when you want to suggest that the GUI be painted
  • call the super method in your painting override
  • create a collection of ovals, perhaps Ellipse2D, and paint them in your painting method via a for loop.
  • Chuck all this AWT code and instead draw in Swing in a JPanel's paintComponent(...) method.
  • Rather than draw individual ellipses, draw lines connecting points. You can change thickness by changing the Stroke.
  • Save each curve drawn onto a BufferedImage which is then drawn in the paintComponent method.

Edit:
For a complete example, please see my answer here: Changing JPanel Graphics g color drawing line

Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • if I were to draw lines connecting points, how would I paint them so that I can actually draw curves? – DirtyWhite Nov 05 '13 at 04:02
  • @DirtyWhite: Your points will be pretty close together, and so the image drawn will be curving if the user draws curves. It will look similar to what you have now, only **connected** and thus **better**. – Hovercraft Full Of Eels Nov 05 '13 at 04:03
  • Oh my. This is a million times better. I just created new variables xO and yO and cycled old x and y values into them to draw a connected line. Thank you so much. – DirtyWhite Nov 05 '13 at 04:07
  • @DirtyWhite: You're still likely making some of the same mistakes. Have you minimized your application and restored it yet? What happens to your image? – Hovercraft Full Of Eels Nov 05 '13 at 04:09
  • It get repainted and thus updated and thus... delted. I am aware of this and will continue to implement your other suggestions. I am just very glad the line is so much more connected now. However, I cant find a method to change the stroke of the line. Is this in the Graphics class? or is it outside of AWT entirely? – DirtyWhite Nov 05 '13 at 04:11
  • @DirtyWhite: it is in Graphics2D: `setStroke(...)`. I usually use a BasicStroke object for this. – Hovercraft Full Of Eels Nov 05 '13 at 04:15
  • @DirtyWhite: see link to my code in the edit to my answer, or check out [this link](http://stackoverflow.com/a/6105437/522444). – Hovercraft Full Of Eels Nov 05 '13 at 04:33