MacRuby DoJo (道場)

Creates a Stopwatch Application

In this content, describe how to create a simple application. This content have some essences to create an application using MacRuby.

Show an application’s User Interface in following figure. We will call this application “StopWatch”.

image

The “StopWatch” has below behaviors.

  1. Run a timer if start button is clicked.
  2. Stop a timer if stop button is clicked.
  3. A timer value is displayed in Text Field.

User Interface

To start the design, need some operations in Xcode.

Choose a MainMenu.xib.

image

Choose a [Window - StopWatch] to display Window for design.

image

Click an icon in toolbar like the following figure. After that, Object Library is displayed.

image

You have been completed to prepare to design. Then, place the User Interface parts from Object Library to Window.

image

Connect the Outlets

The “StopWatch” application sets a timer value into Text Field. However, if Text Field is just placed on Window, cannot set a value into there. We should use the Outlets to set a value or to get a status of User Interface parts.

To use the Outlets, need to write a program code. Choose a AppDelegate.rb. After that, add a attr_accessor :textField to AppDelegate class.

1
2
3
class AppDelegate
  attr_accessor :window
  attr_accessor :textField # Outlet

Return to MainMenu.xib screen, connect the Outlet. Press control key and drag from App Delegate to Text Field.

image

A list of Outlets will be displayed, and then choose a textField to connect it.

image

You can set/get the value of the Text Field through the textField accessor.

Connect the Actions

When you clicked start/stop button, still nothing happens. You need to set the behaviors when the buttons are clicked.

Choose an AppDelegate.rb. After that, add startTimer and stopTimer methods as following.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class AppDelegate
  attr_accessor :window
  attr_accessor :textField # Outlet
  def applicationDidFinishLaunching(a_notification)
    # Insert code here to initialize your application
  end

  def startTimer(sender)
    # This method is called when clicked start button.
  end

  def stopTimer(sender)
    # This method is called when clicked stop button.
  end

end

Return to MainMenu.xib screen, connect the Actions. Press control key and drag from start button to App Delegate.

image

A list of Actions will be displayed, and then choose a startTimer to connect it.

image

Connect stop button to stopTimer in the same way. Each methods will be called when the button is clicked.

stopTimer/startTimer are also known as the action method.

If you write an action method, you must provide a sender argument. If methods does not have a sender argument, it is not recognized as an action method.

Use the timer

If you do something at a constant interval, use the NSTimer.

When use a timer as shown below, you will be able to handle at a constant interval.

1
2
3
4
5
6
7
8
9
10
@timer = NSTimer
           .scheduledTimerWithTimeInterval(0.1,
                                           target: self,
                                           selector: "timerHandler:",
                                           userInfo: nil,
                                           repeats: true)

def timerHandler(userInfo)
  # Handler
end

Generate a timer at startTimer and stop a timer at stopTimer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class AppDelegate
  attr_accessor :window
  attr_accessor :textField # Outlet
  def applicationDidFinishLaunching(a_notification)
    # Insert code here to initialize your application
  end

  def startTimer(sender)
    if @timer.nil?
      @time = 0.0
      @timer = NSTimer
                .scheduledTimerWithTimeInterval(0.1,
                                                target: self,
                                                selector: "timerHandler:",
                                                userInfo: nil,
                                                repeats: true)
    end
  end

  def stopTimer(sender)
    if @timer
      @timer.invalidate
      @timer = nil
    end
  end

  def timerHandler(userInfo)
    @time += 0.1
    string = sprintf("%.1f", @time)
    textField.setStringValue(string)
  end
end

Invoke @timer.invalidate to stop a timer. Invoke textField.setStringValue(string) to set string to Text Field.

“Stopwatch” application is complete!

Change to “StopWatch” from “Deployment” in Scheme. After that, Click [Run]. “Stopwatch” application will be running!!

image

Comments