TheBear
TheBear

Reputation: 13

Java to C# conversion. How do i draw a rectangle on my bitmap?

Firstly, i am a complete noob at both C# and Java.

So i have been given this assignment to convert a java applet into C#, i have managed to do everything apart from drawing a rectangle on the screen via drag and drop using mouse events.

Whats supposed to happen is when i click and drag my mouse across the screen a rectangle with no fill and white border should appear. The code i have below is just a white screen with a red cross through it, if i comment out the if(action) statement in the form1_Paint then it works but no rectangle so it must be that code that messing it up.

http://gyazo.com/b2506b8c2ea9b304e34172c42ce98aab <-- what it should look like

http://gyazo.com/a8764ac9f5380f0109623d7a7750ddb6 <-- what it actually looks like

[update]

I have now got a rectangle do display but it happens on the MouseUp event rather than creating it as i am dragging my mouse. The obvious next step was to move it to a different mouse event like mouseMove but then it really messes up and created rectangles constantly as i make it bigger. How can i make it constantly resize the rectangle as i drag my mouse and not keep creating rectangles constantly? The code

   private void Form1_Paint(object sender, PaintEventArgs e)
    {
        Graphics g1 = e.Graphics;
        g1.DrawImage(bitmap, 0, 0, x1, y1);

    }
    //added load method
    private void Form1_Load(object sender, EventArgs e)//runs functions on load
    {
        init();
        start();

    }
    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if (action)
        {
            xe = e.X;
            ye = e.Y;

        }




    }

    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
        action = true;
        // e.consume();  
        xs = xe = e.X;
        ys = ye = e.Y; // starting point y
         Form1_MouseMove(sender, e);
         this.Invalidate();

    }

    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
          using (Graphics g = this.CreateGraphics())
            {
                Pen pen = new Pen(Color.White);
                g.DrawRectangle(pen, xs, ys, Math.Abs(xs - xe), Math.Abs(ys - ye));

            }

        int z, w;  
        //e.consume();

            //xe = e.X;
            //ye = e.Y;
            if (xs > xe)
            {
                z = xs;
                xs = xe;
                xe = z;
            }
            if (ys > ye)
            {
                z = ys;
                ys = ye;
                ye = z;
            }
            w = (xe - xs);
            z = (ye - ys);
            if ((w < 2) && (z < 2)) initvalues();
            else
            {
                if (((float)w > (float)z * xy)) ye = (int)((float)ys + (float)w / xy);
                else xe = (int)((float)xs + (float)z * xy);
                xende = xstart + xzoom * (double)xe;
                yende = ystart + yzoom * (double)ye;
                xstart += xzoom * (double)xs;
                ystart += yzoom * (double)ys;
            }
            xzoom = (xende - xstart) / (double)x1;
            yzoom = (yende - ystart) / (double)y1;
            mandelbrot();

            this.Invalidate();
            //Repaint();



    }

Upvotes: 0

Views: 567

Answers (2)

Dave Jones
Dave Jones

Reputation: 53

I've had a look here, this doesn't seem to fix my problem, the Invalidate();'s make it stutter and when I have it in Form1_Paint it doesn't draw correctly, either draws before straight onto the form, straight after I've zoomed but doesn't actually appear when I'm dragging in my zoom!

Upvotes: 0

Peter Duniho
Peter Duniho

Reputation: 70652

The biggest problem in your code is this statement in the Form1_Paint() method:

g1.Dispose();

You should never be disposing the Graphics instance passed to you. It belongs to the framework, not your code. But you should especially never dispose an object that you plan to use later. When you dispose it here, then the Graphics instance isn't valid later on when you try to draw the rectangle.

Note that this is the same as in Java. I hope the original Java code didn't call Graphics.dispose() too!

Some other suggestions:

  • when creating a new Pen object, add a using statement to ensure the Pen instance you create is disposed properly (you do own that one! :) ). In this case though, you don't need to create a new Pen object...just use the stock Pen provided by .NET. I.e. Pens.White.
  • you don't appear to be calling Invalidate() in the MouseDown and MouseMove event handlers. You won't get any visual feedback unless you do that, because the Paint event handler won't be called.

Fix the code so it looks like this:

// Little helper method :)
private static void Swap<T>(ref T t1, ref T t2)
{
    T temp = t1;
    t1 = t2;
    t2 = t1;
}

private void Form1_Paint(object sender, PaintEventArgs e)
{
    Graphics g1 = e.Graphics;
    g1.DrawImage(bitmap, 0, 0, x1, y1);

    if (action)
    {
        //g.setColor(Color.White);
        if (xe < xs)
        {
            Swap(ref xs, ref xe);
        }

        if (ye < ys)
        {
            Swap(ref ys, ref ye);
        }

        g1.DrawRectangle(Pens.White, xs, ys, (xe - xs), (ye - ys));
    }
}

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
   // e.consume();
    if (action)
    {
        xe = e.X;
        ye = e.Y;
        Invalidate();
        //repaint();
    }

}

private void Form1_MouseDown(object sender, MouseEventArgs e)
{
    action = true;
    // e.consume();
    if (action)
    {
        xs = xe = e.X;
        ys = ye = e.Y;
        Invalidate();
    }
}

Upvotes: 1

Related Questions