School Assignment? Project Due Tomorrow? Chat LIVE With A Programming Expert!

Welcome to Dream.In.Code
Become an Expert!

Join 300,413 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 1,601 people online right now. Registration is fast and FREE... Join Now!




Basic Object/Class overview: Digital Clock example.

 
Reply to this topicStart new topic

> Basic Object/Class overview: Digital Clock example., Create a digital time clock and understand objects

kryton46
Group Icon



post 4 Jan, 2009 - 04:59 PM
Post #1


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:

CODE

& #39;****************************************************************************
**************'
'****                       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.       ****'
& #39;****************************************************************************
**************'

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:

CODE

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):

CODE

    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 cool.gif
Go to the top of the page
+Quote Post


Register to Make This Ad Go Away!

sam.adams61
**



post 28 Jan, 2009 - 09:18 PM
Post #2
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!
Go to the top of the page
+Quote Post

kryton46
Group Icon



post 28 Jan, 2009 - 11:13 PM
Post #3
QUOTE(sam.adams61 @ 28 Jan, 2009 - 09: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!


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]:

CODE

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:

CODE

Dim myTempString as string
myTempString = DigitalClock.FormattedTime


Let me know if that helps or if i've muddied the waters wink2.gif

This post has been edited by kryton46: 28 Jan, 2009 - 11:16 PM
Go to the top of the page
+Quote Post

sam.adams61
**



post 28 Jan, 2009 - 11:22 PM
Post #4
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. tongue.gif 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):"

CODE
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: 28 Jan, 2009 - 11:59 PM
Go to the top of the page
+Quote Post

Jayman
Group Icon



post 29 Jan, 2009 - 03:29 PM
Post #5
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.
Go to the top of the page
+Quote Post

kryton46
Group Icon



post 29 Jan, 2009 - 07:03 PM
Post #6
QUOTE(Jayman @ 29 Jan, 2009 - 03: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.


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 wink2.gif

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:

CODE

'****                       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:

CODE

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.gif
Go to the top of the page
+Quote Post

Jayman
Group Icon



post 30 Jan, 2009 - 11:18 AM
Post #7
Modified original tutorial to include the correct instructions.
Go to the top of the page
+Quote Post


Fast ReplyReply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 


Lo-Fi Version Time is now: 11/7/09 11:17PM

Live Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month