Question Panel Drawing Errors With Labels On Form

bulsatar

Member
Joined
Mar 4, 2012
Messages
8
Programming Experience
1-3
Hello Everyone,

Branching out in my programming skills and working on creating a simple tetris game in vb.net (going through a tutorial Creating your own Tetris game using VB.NET). Everything works fine until I add labels to the form. They are not overlapping anything and the only code I am running is the initial splash. When I add the labels, the graphics in the panel do not appear anymore. I have verified this behaviour on 3 different attempts in different starter projects. Anyone know what is going on????

code and setup for anyone that doesn't want to go to the site:
1 form (form name: frmTet)
7 labels (text not important right now, default is fine)
2 panels, 1 large, 1 small (large panel is labeled: pnlTetGame, small panel is labeled: pnlTetPreview)

VB.NET:
Public Class frmTet
 Private Sub frmTet_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
  Splash()
 End Sub
 Private Sub Splash()
  Dim gStart As Graphics = pnlTetGame.CreateGraphics() 'Enable Drawing Onto Panel
  gStart.Clear(Color.Black) 'Clear If There Was Something
  'Create H Shape
  gStart.FillRectangle(New SolidBrush(Color.Red), 25, 100, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 25, 100, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Red), 25, 105, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 25, 105, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Red), 25, 110, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 25, 110, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Red), 25, 115, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 25, 115, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Red), 25, 120, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 25, 120, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Red), 30, 110, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 30, 110, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Red), 35, 110, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 35, 110, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Red), 40, 100, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 40, 100, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Red), 40, 105, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 40, 105, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Red), 40, 110, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 40, 110, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Red), 40, 115, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 40, 115, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Red), 40, 120, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 40, 120, 5, 5)
  'Create T Shape
  gStart.FillRectangle(New SolidBrush(Color.Green), 55, 100, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 55, 100, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Green), 60, 100, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 60, 100, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Green), 65, 100, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 65, 100, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Green), 60, 105, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 60, 105, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Green), 60, 110, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 60, 110, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Green), 60, 115, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 60, 115, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Green), 60, 120, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 60, 120, 5, 5)
  'Create G Shape
  gStart.FillRectangle(New SolidBrush(Color.Blue), 85, 100, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 85, 100, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Blue), 90, 100, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 90, 100, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Blue), 80, 105, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 80, 105, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Blue), 80, 110, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 80, 110, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Blue), 80, 115, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 80, 115, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Blue), 85, 120, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 85, 120, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Blue), 90, 120, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 90, 120, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Blue), 95, 115, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 95, 115, 5, 5)
  gStart.FillRectangle(New SolidBrush(Color.Blue), 100, 115, 5, 5)
  gStart.DrawRectangle(New Pen(Color.White, 1), 100, 115, 5, 5)
 End Sub

End Class

Thanks for any help!!!
 
There are several other non-fatal but serious issues with your code related to resource management. Firstly, if you were going to call CreateGraphics then it's very important that, just like any other disposable object, you dispose the object you create when you are finished with it. If you don't then you have a resource leak. If your Paint event was to be raised many times then you will have many undisposed Graphics objects left in memory, all consuming system resources. You could dispose the object explicitly like this:
Dim gStart As Graphics = pnlTetGame.CreateGraphics()

'...
gStart.Dispose()
but the preferred way to dispose an object in the same scope is was created in is like this:
Using gStart As Graphics = pnlTetGame.CreateGraphics()
    '...
End Using
That said, you shouldn't be calling CreateGraphics at all. You should pretty much never call CreateGraphics. The Paint event of the control creates the Graphics object and disposes it, so there's no need for you to worry about that. That Graphics object is available to you via the e.Graphics property.

Also, you are creating a new Brush every time you call FillRectangle and a new Pen every time you call DrawRectangle. That's bad enough in itself but you don't dispose any of them either, so you're creating a big resource leak. If you were going to create those Brushes and Pens then you would do it once only and then reuse them:
Using whitePen As New Pen(Color.White, 1)
    Using redBrush As New SolidBrush(Color.Red)
        '...
    End Using

    Using greenBrush As New SolidBrush(Color.Green)
        '...
    End Using

    Using blueBrush As New SolidBrush(Color.Blue)
        '...
    End Using
End Using
Yet again though, there's no need for you to create those objects explicitly:
Dim whitePen = Pens.White
Dim redBrush = Brushes.Red
Dim greenBrush = Brushes.Green
Dim blueBrush = Brushes.Blue
 
Thanks jmcilhinney ! You always assume that the tutorial you are following is doing the right thing until you know a little more...I will keep your advice and see if I can start finding other improvements based on what you have said.

~~Made just some of the changes (and I have some ideas for a few more) and it runs much faster! From previous vba experience, I was wondering why that tut was setting a new thing every time as that is not how I normally program but again, I assumed...

In general, when do you have to dispose of an object? For instance, when I created the brush variables, at the end I told it to dispose (didn't use Using as want to experiment and get a feel for the language) but got an error, erased the dispose and ran just fine.

Thanks again, very helpful!
 
Last edited:
Also, I am not a fan of how that person listed each of the rectangles separately for each fill and rectangle. So, here is how I would "normally" have written it but again, was just trying to follow the tutorial...

Just letter H
VB.NET:
'Create H Shape
[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2]letH = [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]New[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]Integer[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2]() {25, 100, 25, 105, 25, 110, 25, 115, 25, 120, 30, 110, _
35, 110, 40, 100, 40, 105, 40, 110, 40, 115, 40, 120}
[/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]For[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] i = LBound(letH) [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]To[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] UBound(letH)
gStart.FillRectangle(redBrush, letH(i), letH(i + 1), 5, 5)
gStart.DrawRectangle(whitePen, letH(i), letH(i + 1), 5, 5)
i = i + 1
[/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]Next[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] i
 
If you create an instance of a disposable object you must call Dispose before releasing last reference to that object. Typically you are creating objects when you use the New keyword. Otherwise a method that returns a created object usually documents this behaviour, for example help for the previously used CreateGraphics method explains:
The returned Graphics must be disposed through a call to its Dispose method when it is no longer needed.
The shared Brushes properties returns shared system brushes, you are not creating these brushes so you don't dispose them either.
 
Back
Top