Page 1 of 1

Basic Object/Class overview: Digital Clock example. Create a digital time clock and understand objects Rate Topic: -----

#1 kryton46  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 6
  • View blog
  • Posts: 44
  • Joined: 29-December 08

Post icon  Posted 04 January 2009 - 05:59 PM

I just wanted to share with fellow beginners, how to use a timer to show correctly formatted time like [HH:MM:SS:tenths] on a label or text box placed on a form and implementing a simple class and object.

Let me explain my interpretation of classes. When i first started learning OO design, objects baffled me as i was used to procedural VB6.0 syntax! However, the simplicity of objects began to slowly sink in (and reading many eBooks) and they are powerful for one main reason - objects encapsulate code, i.e. think of objects as a shoe box; all your code is stuffed into a shoe box and you don't need to care what the code is, all you care about is what methods and properties are available. Don't worry about things like inheritance, delegates, reflection, polymorphism, etc, they are all scare words you don't need to know about when first understanding OO, just understand that classes are black boxes of code and the battle is half won.

Using intellisense shows you this easily (much better in VB than C# imho, but i'm a noob, so i may stand corrected). For example, dropping a text box on a form, if you type textbox1. then intellisense shows you all the methods and properties (class variables) available. You don't care how the code is written, just that it is there as a simple function call like textbox1.text or textbox1.width, etc.

I also thought along these lines when i first began to learn OO; imagine you create a simple form with buttons, labels, text boxes, etc and then view the form1.vb code (double click form in design view). This is called client code and think of it as the right page of a book. Now if you create an object, this would be the left page, so the left and right pages are two distinct entities separated by the spine of the book. The only way the two pages can 'talk' to one another is by creating an instance of the class in the client code (right page) by doing Dim myObject as New Object. You can now access all methods and properties of the left hand page (class). Here, myObject is code in the right hand page analogy and Object is the class code in the left hand page. The compiler now acts like the spine of the book and links the two code spaces together, so you now have at your disposal an object called myObject that lives in memory, ready to be used.

The class is completely separate and autonomous from your forms client code and so it easily extensible for future amendments without breaking other code elsewhere. You can create many left pages (classes) and many forms (right pages) without the two ever becoming dependant on each other. You can link any left and right page by instantiating objects in the forms client code where you wish to use the object.

The whole point i've found about the importance of OO is that with procedural languages (old school VB) you can easily end up with spaghetti code (all over the place with no structure). With OO, you are separating code as it relates to distinct actions on a form for example. If designed well, it's easy to code months later as you only ever need to worry about the scope of the class code and not the whole project in general.

This snippet shows you the basics of using a Timer control on your form, creating a basic object from a class in your project and some looping to validate which numbers to display; so let's begin.

1. Create a new VB project [File/New Project] and choose [Windows Forms Application], name it what you want
2. In your solution explorer you should now have [My Project] & [Form1.vb]
3. Right click your project name in solution explorer (the one in bold) and add a class. Name it [Timer] and paste this code into the new Timer class:

'******************************************************************************************'
'****					   METHODOLOGY USED FOR CLASS DESIGN						  ****'
'****					   ---------------------------------						  ****'
'**** On every tick event, need to format the value so it's [HH:MM:SS:tenths] and	  ****'
'**** increment [m_TimerValue] by 1. Then set [m_FormattedTime] variable so it can be  ****'
'**** read by calling procedure in [MainForm] through its associated property.	   ****'
'******************************************************************************************'

Public Class Timer

'Private class variables (called fields). These are only accessible by methods inside the class!
	Private m_TimerValue As Integer
	Private m_FormattedTime As String
	Private m_Hour As Integer
	Private m_Minute As Integer
	Private m_Seconds As Integer
	Private m_Tenths As Integer

#Region "Property declarations"

	   'Use a public property so the forms client code can retrieve the data held in the above class fields. 
	   'Properties are a gateway to access class data!
	Public Property FormattedTime() As String
		Get
			Return m_FormattedTime
		End Get
		Set(ByVal value As String)
			m_FormattedTime = value
		End Set
	End Property

#End Region

#Region "Class constructor"

	'*** CLASS CONSTRUCTOR ***
		'When the object is first created in the forms client code, the [New] method is always invoked first; use this to 
		'set up the class variables, so we are forcing correct data into the properties. 
	Public Sub New()
		'Set [m_TimerValue] to 1 so the [FormatTime] method formats correctly on first loop.
		'If it's set to 0, then on first loop [m_TimerValue] isn't synced properly to the loop and
		'against [HH:MM:SS:tenths].
		m_TimerValue = 1
		m_FormattedTime = ""
		m_Hour = 0
		m_Minute = 0
		m_Seconds = 0
		m_Tenths = 0
	End Sub

#End Region

#Region "Format timer"

		'This method is called every time the [Timer] on the form 'ticks'. So if you set the timers interval to 1000, for
		'example (1second) then every second this class method is called. Because we want tenths of a second
		'to show, we set the timer interval to 100 = 0.1secs, i.e. the timer fires 10 times every second and when it
		'does we can work out which number in the [HH:MM:SS:tenths] to change, depending on the m_TimerValue
		'counter value.
	Public Sub TimerTick()

		FormatTime()
		m_TimerValue += 1

	End Sub

	Public Sub ResetTimerValue()

		m_TimerValue = 1

	End Sub

	Private Sub FormatTime()

		   'Waterfall conditional check. Basically the m_TimerValue is incremented by one every time the [TimerTick]
			   'is called above. If the value is less than 10 then it is just adds 1 to m_Tenths. If it equals 10 then we 
			   'have reached the end of tenths so we need to increase the seconds value by one and reset 
			   'm_TimerValue and m_Tenths to zero. Carry on doing this and if m_Seconds reaches 59 then we are 
			   'ready to increment the minutes value [m_Minute] by one; same happens when minutes reaches 59 and so
			   'now change the hour value. Carry on doing this if you want days, weeks, years, etc by nesting the 
			   'conditional 'trap' checks to see if values exceed the upper limit of the variable, e.g. minutes(59),
			   'hours(24), days(7), etc, etc.

		If m_TimerValue = "10" Then
			m_TimerValue = 0
			m_Tenths = 0
			If m_Seconds = 59 Then
				m_Seconds = 0
				If m_Minute = 59 Then
					m_Minute = 0
					If m_Hour = 59 Then
						m_Hour = 0
					Else
						m_Hour += 1
					End If
				Else
					m_Minute += 1
				End If
			Else
				m_Seconds += 1
			End If
		Else
			m_Tenths += 1
		End If

		'Convert to strings (as we are using a label or text box on the form. Determine if result of Hour, 
				'Minute or second is a single digit, if so then want each string to be two significant figures so Label.Text is 
				'same length. 

		Dim sHour As String = m_Hour.ToString
		Dim sMinute As String = m_Minute.ToString
		Dim sSecond As String = m_Seconds.ToString

		If sSecond.Length = 1 Then
			sSecond = "0" + sSecond
		End If
		If sMinute.Length = 1 Then
			sMinute = "0" + sMinute
		End If
		If sHour.Length = 1 Then
			sHour = "0" + sHour
		End If

		'Final format of Time String now available to 'client code'
		m_FormattedTime = sHour + ":" +  sMinute + ":" + sSecond + ":" + m_Tenths.ToString
		
	End Sub


	   'Can reset the digital clock on the form by calling this method.
	Public Sub ZeroHHMMSS()
		m_Hour = 0
		m_Minute = 0
		m_Seconds = 0
		m_Tenths = 0
	End Sub

#End Region

End Class



======================================================================

In your MainForm (Form1, for example) create a timer control by selecting it from the toolbox and dragging it to your form. It should appear in the bottom panel/container; set it's interval in properties box (on right) to 100. Now we can create an object of our timer class. Instantiate the following object at the class level of your form:

Public Class Form1

	Private DigitalClock As New Timer()

	Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

	End Sub


End Class



Put a Timer Control on the form and a label and use this line of code in the timer tick events (double click timer control):

	Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
		Label1.Text = DigitalClock.FormattedTime
		DigitalClock.TimerTick()
	End Sub

	Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
		Timer1.Enabled = True
	End Sub




Hope that helps anyone trying to format time on their forms and more importantly using a basic class & object B)

Is This A Good Question/Topic? 0
  • +

Replies To: Basic Object/Class overview: Digital Clock example.

#2 sam.adams61  Icon User is offline

  • D.I.C Regular

Reputation: 12
  • View blog
  • Posts: 283
  • Joined: 14-July 08

Posted 28 January 2009 - 10:18 PM

Was getting on fine with this until I entered the last line of code...it seems that FormattedTime is not a member of the DigitalClock. Wonder can you explain this? Many thanks!
Was This Post Helpful? 0
  • +
  • -

#3 kryton46  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 6
  • View blog
  • Posts: 44
  • Joined: 29-December 08

Posted 29 January 2009 - 12:13 AM

View Postsam.adams61, on 28 Jan, 2009 - 09:18 PM, said:

Was getting on fine with this until I entered the last line of code...it seems that FormattedTime is not a member of the DigitalClock. Wonder can you explain this? Many thanks!


The [FormattedTime] is a read/write Property of the class. The [m_FormattedTime] variable is only ever seen by the DigitalClock class, hence it's 'm_' prefix (just a way to say it is a class member and can't be seen elsewhere). btw, C# snobs prefer to use just '_variableExample' but it is a matter of preference. So using the following we can access the private variable [m_FormattedTime]:

Public Property FormattedTime() As String
		Get
			Return m_FormattedTime
		End Get
		Set(ByVal value As String)
			m_FormattedTime = value
		End Set
	End Property




So basically, you can read the value of [m_FormattedTime] from any other piece of code that uses this object with the following statement, without worrying about all the 'crunching' going on in the background:

Dim myTempString as string
myTempString = DigitalClock.FormattedTime



Let me know if that helps or if i've muddied the waters ;)

This post has been edited by kryton46: 29 January 2009 - 12:16 AM

Was This Post Helpful? 0
  • +
  • -

#4 sam.adams61  Icon User is offline

  • D.I.C Regular

Reputation: 12
  • View blog
  • Posts: 283
  • Joined: 14-July 08

Posted 29 January 2009 - 12:22 AM

Still not getting anywhere...I know there shoul'nt be a problem, as I copied your code line for line. Anyway, I'll check through it all again...just in case I've missed something. Many thanks for your kind reply. May your giving hand never fall off. :P BTW, are you asking for a second Timer Control here: quote "Put a Timer Control on the form and a label and use this line of code in the timer tick events (double click timer control):"

 Private Sub TimerControl_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerControl.Tick

	 label1.Text = DigitalClock.FormattedTime 

This post has been edited by sam.adams61: 29 January 2009 - 12:59 AM

Was This Post Helpful? 0
  • +
  • -

#5 Jayman  Icon User is offline

  • Student of Life
  • member icon

Reputation: 418
  • View blog
  • Posts: 9,532
  • Joined: 26-December 05

Posted 29 January 2009 - 04:29 PM

I see an issue where you declare the object in the Load event, but try to access its property in the Tick event of a timer. This won't work, you need to declare the object at the class level or instantiate it in the Tick event, before you can access its properties.

I am surprised you were able to compile it, unless there is more to the code than you posted.
Was This Post Helpful? 0
  • +
  • -

#6 kryton46  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 6
  • View blog
  • Posts: 44
  • Joined: 29-December 08

Posted 29 January 2009 - 08:03 PM

View PostJayman, on 29 Jan, 2009 - 03:29 PM, said:

I see an issue where you declare the object in the Load event, but try to access its property in the Tick event of a timer. This won't work, you need to declare the object at the class level or instantiate it in the Tick event, before you can access its properties.

I am surprised you were able to compile it, unless there is more to the code than you posted.


Sorry for the mistakes; i didn't create a new project to test it, the arrogance (or excitement) of trying to help others with my first tutorial. Again sorry to fellow noobs, i understand your frustration trying to make 'dodgy' code work.

I have taken Jayman's advice (thanks) and re-worked and tested the mini-project and it now works fine ;)

So let's start from the beginning:

1. Create a new Windows application so you have the generic [Form1].
2. Right click the project and add a class called [Timer].
3. On the form add a label called [label1], a button called [Button1] and drag a timer control from the toolbox onto the form
4. Add this code to the [Timer] class:

'****					   METHODOLOGY USED FOR CLASS DESIGN						  ****'
'****					   ---------------------------------						  ****'
'**** On every tick event, need to format the value so it's [HH:MM:SS:tenths] and	  ****'
'**** increment [m_TimerValue] by 1. Then set [m_FormattedTime] variable so it can be  ****'
'**** read by calling procedure in [MainForm] through its associated property.	   ****'


Public Class Timer

	'Private class variables (called fields). These are only accessible by methods inside the class!
	Private m_TimerValue As Integer
	Private m_FormattedTime As String
	Private m_Hour As Integer
	Private m_Minute As Integer
	Private m_Seconds As Integer
	Private m_Tenths As Integer

#Region "Property declarations"

	'Use a public property so the forms client code can retrieve the data held in the above class fields.
	'Properties are a gateway to access class data!
	Public Property FormattedTime() As String
		Get
			Return m_FormattedTime
		End Get
		Set(ByVal value As String)
			m_FormattedTime = value
		End Set
	End Property

#End Region

#Region "Class constructor"

	'*** CLASS CONSTRUCTOR ***
	'When the object is first created in the forms client code, the [New] method is always invoked first; use this to
	'set up the class variables, so we are forcing correct data into the properties.
	Public Sub New()
		'Set [m_TimerValue] to 1 so the [FormatTime] method formats correctly on first loop.
		'If it's set to 0, then on first loop [m_TimerValue] isn't synced properly to the loop and
		'against [HH:MM:SS:tenths].
		m_TimerValue = 1
		m_FormattedTime = ""
		m_Hour = 0
		m_Minute = 0
		m_Seconds = 0
		m_Tenths = 0
	End Sub

#End Region

#Region "Format timer"

	'This method is called every time the [Timer] on the form 'ticks'. So if you set the timers interval to 1000, for
	'example (1second) then every second this class method is called. Because we want tenths of a second
	'to show, we set the timer interval to 100 = 0.1secs, i.e. the timer fires 10 times every second and when it
	'does we can work out which number in the [HH:MM:SS:tenths] to change, depending on the m_TimerValue
	'counter value.
	Public Sub TimerTick()

		FormatTime()
		m_TimerValue += 1

	End Sub

	Public Sub ResetTimerValue()

		m_TimerValue = 1

	End Sub

	Private Sub FormatTime()

		'Waterfall conditional check. Basically the m_TimerValue is incremented by one every time the [TimerTick]
		'is called above. If the value is less than 10 then it is just adds 1 to m_Tenths. If it equals 10 then we
		'have reached the end of tenths so we need to increase the seconds value by one and reset
		'm_TimerValue and m_Tenths to zero. Carry on doing this and if m_Seconds reaches 59 then we are
		'ready to increment the minutes value [m_Minute] by one; same happens when minutes reaches 59 and so
		'now change the hour value. Carry on doing this if you want days, weeks, years, etc by nesting the
		'conditional 'trap' checks to see if values exceed the upper limit of the variable, e.g. minutes(59),
		'hours(24), days(7), etc, etc.

		If m_TimerValue = "10" Then
			m_TimerValue = 0
			m_Tenths = 0
			If m_Seconds = 59 Then
				m_Seconds = 0
				If m_Minute = 59 Then
					m_Minute = 0
					If m_Hour = 59 Then
						m_Hour = 0
					Else
						m_Hour += 1
					End If
				Else
					m_Minute += 1
				End If
			Else
				m_Seconds += 1
			End If
		Else
			m_Tenths += 1
		End If

		'Convert to strings (as we are using a label or text box on the form. Determine if result of Hour,
		'Minute or second is a single digit, if so then want each string to be two significant figures so Label.Text is
		'same length.

		Dim sHour As String = m_Hour.ToString
		Dim sMinute As String = m_Minute.ToString
		Dim sSecond As String = m_Seconds.ToString

		If sSecond.Length = 1 Then
			sSecond = "0" + sSecond
		End If
		If sMinute.Length = 1 Then
			sMinute = "0" + sMinute
		End If
		If sHour.Length = 1 Then
			sHour = "0" + sHour
		End If

		'Final format of Time String now available to 'client code'
		m_FormattedTime = sHour + ":" + sMinute + ":" + sSecond + ":" + m_Tenths.ToString

	End Sub


	'Can reset the digital clock on the form by calling this method.
	Public Sub ZeroHHMMSS()
		m_Hour = 0
		m_Minute = 0
		m_Seconds = 0
		m_Tenths = 0
	End Sub

#End Region

End Class




5. Add this code to the [Form1] class:

Public Class Form1

	Private DigitalClock As New Timer()

	Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

	End Sub

	Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
		Label1.Text = DigitalClock.FormattedTime
		DigitalClock.TimerTick()
	End Sub

	Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
		Timer1.Enabled = True
	End Sub
End Class



6. Fire it up and click the button :rolleyes:
Was This Post Helpful? 0
  • +
  • -

#7 Jayman  Icon User is offline

  • Student of Life
  • member icon

Reputation: 418
  • View blog
  • Posts: 9,532
  • Joined: 26-December 05

Posted 30 January 2009 - 12:18 PM

Modified original tutorial to include the correct instructions.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1