<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Singleton &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/singleton/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Wed, 25 Sep 2024 14:26:18 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Update: ipify for Xojo</title>
		<link>https://blog.xojo.com/2021/09/03/update-ipify-for-xojo/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Fri, 03 Sep 2021 15:57:11 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[ipify]]></category>
		<category><![CDATA[Singleton]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9163</guid>

					<description><![CDATA[There are plenty of times when your Xojo apps might need to know the public or external IP address is, and there are a lot of web sites or services that you can use with Xojo to find that. I found ipify to be easy to use]]></description>
										<content:encoded><![CDATA[
<p><strong>This post was originally posted in <a href="https://blog.xojo.com/2017/09/26/ipify-for-xojo/">2017</a> and has been updated in this post using Xojo API 2.0.</strong></p>



<p><a href="https://www.ipify.org/">ipify</a> is a very useful web service (an API) that promises to always be available to attend requests, letting us know the public (or external) IP address we are using to connect to Internet. We can get this information as pure Text or in <strong>JSON</strong> or <strong>XML</strong> formats.</p>



<p>There are plenty of times when your Xojo apps might need to know the public or external IP address is, and there are a lot of web sites or services that you can use with Xojo to find that.</p>



<p>I found ipify to be easy to use, plus it is easily available due to being hosted by <a href="http://heroku.com/">Heroku</a>. That means, for example, that if half the Internet is down…you still can be confident to reach the ipify service.</p>



<p>Using ipify from a Xojo desktop apps is as simple as using this code:</p>



<p><code>Var request as New URLConnection<br>Dim s as String = request.SendSync("GET","https://api.ipify.org",10)</code></p>



<p>But sometimes we need additional information; for example if the IP address has changed over time, or simply periodically checking for IP address changes. That is something that you can find in the <a href="https://www.dropbox.com/s/87zq4ksgq8tlaon/IPify.xojo_binary_project.zip?dl=1">ipify project for Xojo available here</a>.</p>



<p><strong>ipify for Xojo</strong> is designed as a <a href="https://blog.xojo.com/2016/06/08/design-patterns-in-xojo-singleton/">Singleton class</a>, that means that you even don’t need to instatiate it in order to get the current IP address, know if the IP has changed over time, or even instruct the class to periodically check for the IP address, notifying the registered object every time with the current IP address and if it is the same or has changed from the last time it was checked.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Create a Preferences Class with Operator_Lookup</title>
		<link>https://blog.xojo.com/2018/06/20/create-a-preferences-class-with-operator_lookup/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Wed, 20 Jun 2018 10:00:58 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Constructor]]></category>
		<category><![CDATA[Method Overload]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[Singleton]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=4381</guid>

					<description><![CDATA[Create a Preferences Class with Operator_Lookup: We have at our disposal an operator we can overload: Lookup. Let's explore those advantages and features while building a Preferences class we can use in any of our projects.]]></description>
										<content:encoded><![CDATA[<p>Xojo is an <a href="https://en.wikipedia.org/wiki/Object-oriented_programming">Object Oriented Programming Language</a> and, among other things, that means that it supports <a href="https://blog.xojo.com/2016/05/25/methods-overloading-computed-properties-setters-and-getters/">Methods Overloading</a>. We have seen in other posts that some of these overloaded methods can be Class Constructors, but, there are others things you can do. For example, we can overload the operators. These are the methods in charge of adding two instances of the same class, subtracting, multiplying or dividing them. But we also have at our disposal another operator we can overload: <b>Lookup</b>. What advantages does this give us and how it does it work? Let&#8217;s explore it while building a Preferences class we can use in any of our projects.<span id="more-4381"></span></p>
<p>When we define and implement the <b>Operator_Lookup</b> method in our classes, we will be able to use the dot notation to access and assign a value to a class member that has not been defined for the class! That is, it will be the code implemented in this method that will decide how it will act, not the Xojo Compiler. Among other possibilities, this will bring us the flexibility to create a Preferences class that is not attached to a particular project, and that is multiplatform, of course, backed by as many pairs of Keys/Values in a Dictionary as we need to store our apps preferences. This way we can use the simple dot notation both to store and assign the stored values. Let&#8217;s put this into practice.</p>
<p>The first step is adding a new Class item to the project without assigning a Super class; that is, this will be a base class. For this example, we will use <code>MyPreferences</code> as the name of the class. Then, we will add a property with <code>Data</code> as the Name and <code>Xojo.Core.Dictionary</code> as the data type, setting its scope to Private (this means that the property will be accessible only from the own class). This property will act as the storage for the Key/Value pairs used for our Preference Class.</p>
<p>Add now a new <b>Constructor</b> method in charge of initializing the just defined Dictionary property:</p>
<ul>
<li><b>Name</b>: Constructor</li>
<li><b>Scope</b>: Public</li>
</ul>
<p>And put this line of code in the Code Editor for the Constructor method:</p>
<pre>Data = New Xojo.Core.Dictionary</pre>
<p>Now we will add the method that we are really interested in. This is, the overload for the Operator_Lookup method:</p>
<ul>
<li><b>Name</b>: Operator_Lookup</li>
<li><b>Parameters</b>: key as string, assigns value as auto</li>
<li><b>Scope</b>: Public</li>
</ul>
<p>Writing the following line of code in the resulting Code Editor:</p>
<pre>data.Value( key ) = value</pre>
<p>Once implemented, we can take advantage of the feature. If we add the Open Event to the project and write the below snippet of code, we will see how we can use the dot notation to use and access class members that have never been added to the class. These members are <em>captured</em> by the <code>Operator_Lookup</code> method, adding the member as the key for a new entry in the dictionary (this is the text we write after the dot) and assigning to it the value we put after the equal symbol (the assignation operator); thanks to the use of the <code>assigns</code> keyword in the parameters declaration for the <code>Operator_Lookup</code> method.</p>
<pre>Dim pr As New MyPreferences
pr.page = 10
pr.index = "20"
pr.baseColor = &amp;c204060</pre>
<p>As you can see, <code>Page</code>, <code>Index</code> and <code>BaseColor</code> are not members of our class; these are captured as Keys for the Dictionary thanks to the Operator_Lookup operator. In addition, you can see how we can assign several types of values to these: an Integer, a String and a Color value.</p>
<h2>Retrieving data with Operator_Lookup</h2>
<p>Now, how can we retrieve values for these not existing members using the dot notation? As you probably guessed, we need to add an additional method that overloads Operator_Lookup. In this case the method signature will accept as the parameter the Key we want to retrieve (the class member put after the dot), returning always a String, in order to simplify this example. Thus, add a new method for the class using the following signature:</p>
<ul>
<li><b>Name</b>: Operator_Lookup</li>
<li><b>Parameters</b>: Key As String</li>
<li><b>Return Type</b>: String</li>
<li><b>Scope</b>: Public</li>
</ul>
<p>Writing the following code in the associated Code Editor:</p>
<pre>Dim a As Auto
Dim s As String
If data.HasKey(key) Then
  a = data.Value(key)
  Dim info As Xojo.Introspection.TypeInfo
  info = xojo.Introspection.GetType(a)
  If info = GetTypeInfo(Text) Or info = GetTypeInfo(String) Then
    s = a
  Elseif info = GetTypeInfo(Integer) Then
    s = CType(a, Integer).totext
  Elseif info= GetTypeInfo(Color) Then
    Dim c As Color = a
    s = Str(c)
  End If
End If
Return s</pre>
<p>As you can see, and after verifying that the Dictionary has the Key, we use the <b>Introspection</b> mechanisms provided by the language in order to see what type is associated with the key. Once we have its type, we will convert the value to a String using the appropriate approach for each case: an Integer, a Text/String or a Color. Of course, for brevity, this example doesn&#8217;t take into account other possible value types; but that is something you can implement yourself!</p>
<p>Let&#8217;s go back to the Open Event for the project and add the following line of code at the end:</p>
<p><code>MsgBox pr.page + EndOfLine + pr.index  + EndOfLine + pr.baseColor</code></p>
<p>Run it and observe how we can assign values and retrieve them (always as a String) simply using the dot notation. We can take this class from one project to other and use the dot notation to reference the elements we want to save and retrieve as preferences.</p>
<p><iframe title="Obtén la máxima flexibilidad con Operator_Lookup" width="500" height="375" src="https://www.youtube.com/embed/Tya8tbi9xIM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></p>
<h2>Final Word</h2>
<p>If you decide to use this approach for your projects, there are some considerations you have to take into account. For example, you will not be able to take advantage of the Autocompletion feature provided by the IDE. In addition, we will have to pay special attention to write exactly the same &#8220;member&#8221; in all the cases we want refer to it; otherwise we will be using a different key with unexpected results. After all, once implemented, Operator_Lookup for the class the Compiler will not complain about the undefined members you are trying to access!</p>
<p>It would also be very easy to expand the class so it can work with other data types; adding an additional method to serialize the Key/Values pairs so they can be stored on file/database for a later retrieval and reconstruction via an additional Constructor. Finally, it is very probable that you only want to use a MyPreferences instance in your app, so you could implement this class as a <a href="https://blog.xojo.com/2016/06/08/design-patterns-in-xojo-singleton/">Singleton</a>. Do you dare? If you do, <a href="https://twitter.com/AprendeXojo">tell me about it</a>!</p>
<p><em>Javier Rodri­guez has been the Xojo Spanish Evangelist since 2008, he’s also a Developer, Consultant and Trainer who has be using Xojo since 1998. He manages <a href="http://www.aprendexojo.com">AprendeXojo.com</a> and is the developer behind the GuancheMOS plug-in for Xojo Developers, Markdown Parser for Xojo, HTMLColorizer for Xojo and the Snippery app, among others</em></p>
<p>*<a href="https://www.aprendexojo.com/2018/06/comprobar-y-anadir-valores-en-tiempo-de-ejecucion/">Read this post in Spanish</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Design Patterns in Xojo: Observer, Part II</title>
		<link>https://blog.xojo.com/2016/11/15/design-patterns-observer-part-ii/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 15 Nov 2016 07:24:08 +0000</pubDate>
				<category><![CDATA[Learning]]></category>
		<category><![CDATA[AprendeXojo]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[Object-Oriented]]></category>
		<category><![CDATA[Observer]]></category>
		<category><![CDATA[Singleton]]></category>
		<guid isPermaLink="false">http://blog.xojo.com/?p=2070</guid>

					<description><![CDATA[In previous blog entries we saw how easy it is to implement the Design Pattern Singleton and how we can find the Observer Design Pattern&#8230;]]></description>
										<content:encoded><![CDATA[<p>In previous blog entries we saw how easy it is to implement the Design Pattern <a href="http://blog.xojo.com/2016/06/08/design-patterns-in-xojo-singleton/">Singleton</a> and how we can find the <a href="http://blog.xojo.com/2016/06/15/design-patterns-in-xojo-observer-part-1/">Observer</a> Design Pattern already implemented on several Xojo features by default, greatly simplifying our code and interaction between the objects. Now, as promised, it is time to put it all in practice, creating our own Notification Center: a class that will allow us to share the same unique instance for the entire App (Singleton), and that can use any object in order to register itself for receiving notifications by the observed Control, for one or more message (the notifications themselves).<span id="more-2070"></span><br />
In addition, the designed Class will allow you to unsubscribe any of the previously registered objects, either to stop receiving notifications by the observed object at all, or just some of the previously registered notifications.</p>
<p>The <a href="http://blog.xojo.com/2016/06/08/design-patterns-in-xojo-singleton/">Singleton</a> and <a href="http://blog.xojo.com/2016/06/15/design-patterns-in-xojo-observer-part-1/">Observer</a> Design Patterns have been described in previous blog entries and I highly recommend to read them now so you can get the flavor of the fundamentals behind them. I&#8217;ll wait here for you, I promise! Then we will deal with the code that varies to implement our <strong>NotificationCenter</strong> class, and to put it in practice with a Desktop example project.</p>
<p>Of course, before of continuing reading, you can <a href="https://www.dropbox.com/s/ry6ip9oe5jkm4av/Xojo-Observer-II.zip?dl=1">download the example project,</a> run it and review the code to get a first glance of what it does and how it works. Then, you can come back and continue reading if you want to better understand the <strong>NotificationCenter</strong> class inner, or how other objects can use this class.</p>
<h2>The NotificationCenter Class</h2>
<p>Execute the <strong>Xojo</strong> IDE and create a new Desktop project. Add a new class using <strong>Insert &gt; Class</strong>. Go to the Inspector and change the <strong>Name</strong> attribute to &#8220;NotificationCenter&#8221;. This is the name of the new class we are designing (and, thus, a new Data Type).</p>
<p>With the new class still selected in the Navigator (the leftmost column on the Xojo IDE), add a new <strong>Shared Property</strong> (<strong>Insert &gt; Shared Property</strong>). Use the Inspector again to change the <strong>Name</strong> attribute to &#8220;Instance&#8221;, the Type field to &#8220;NotificationCenter&#8221; and the <strong>Scope</strong> to &#8220;Private&#8221;. (You know, a Shared Property or Shared Method are those that you can access from the class itself, without needing to create previously a new instance from the class.)</p>
<p>Add a second Property to the class, this time via <strong>Insert &gt; Property</strong> (this is, an instance property). Use this values on the associated Inspector:</p>
<ul>
<li><strong>Name:</strong> Objects</li>
<li><strong>Type:</strong> Xojo.Core.Dictionary</li>
<li><strong>Scope:</strong> Private</li>
</ul>
<p>Next, add a new Method (<strong>Insert &gt; Method</strong>). Use the Inspector to choose the <strong>Constructor</strong> option from the &#8220;Method Name&#8221; dropdown menu, and set the method Scope to Private.</p>
<p>Write the following code on the associated Code Editor for the method:</p>
<pre>Objects = new xojo.core.Dictionary</pre>
<p>Defining the Constructor method with a Private scope prohibits the creation of several instances from the class. Instead of that, the class consumers will have to use the convenience method defined by us in order to retrieve the same —and unique— instance for all the cases.</p>
<p>So, now we will add a new Shared Method using <strong>Insert &gt; Shared Method</strong>. Use the Inspector to put the following values on the created method:</p>
<ul>
<li><strong>Name:</strong> SharedInstance</li>
<li><strong>Return Type:</strong> NotificationCenter</li>
</ul>
<p>And write the following code in the associated Code Editor for the method:</p>
<pre>if instance = nil then instance = new NotificationCenter
Return instance</pre>
<p>These are the wires to write our Singleton class and to define our Data Model: the &#8220;Objects&#8221; property of data type <a href="http://developer.xojo.com/xojo-core-dictionary"><strong>Xojo.Core.Dictionary</strong></a>. This property will be responsible for storing the registered objects as observers of the desired Control(s), as well as the messages for whom it is interested in receiving notifications for the observed object(s). Probably this is better understood in the following figure:</p>
<p><img fetchpriority="high" decoding="async" class="size-full wp-image-2072 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2016/11/DataModel.png" alt="Data Model for Notification Center Class" width="485" height="551" />That is, the &#8220;Observers&#8221; Xojo.Core.Dictionary Property uses as <strong>Key</strong> any object of <a href="http://developer.xojo.com/rectcontrol">RectControl</a> data type (the observed object). The associated value for that key is a new Xojo.Core.Dictionary, whose entries will use as Key the Notification (message as Text data type) for what an object wants to register as observer for such Control.</p>
<p>This way, one same object can be registered to several controls and also to several messages (Notifications) on one or several controls.</p>
<p>Finally, the associated value for every <strong>Key</strong> on this second Xojo.Core.Dictionary is an <strong>Array</strong> data type whose items are instances of the <strong>NotificationReceiver</strong> data type.</p>
<p>I know, I know… Stop. Breathe. Execute again the example project. Review the code on the &#8220;Register&#8221; method to get a better grasp… and back to follow!</p>
<h3>Registering Observers</h3>
<p>With the class still selected on the Navigator, add a new method (<strong>Insert &gt; Method</strong>) using the following values. This is the method responsible for registering the new observers on the shared Notification Center instance:</p>
<ul>
<li><strong>Name:</strong> Register</li>
<li><strong>Parameters:</strong> sourceControl as NotificationReceiver, observedObject as RectControl, message as Text</li>
<li><strong>Scope:</strong> Public</li>
</ul>
<p>As you can see in &#8220;Parameters&#8221;, the first parameter is the Observer object (this is the interesed object in receiving the notifications); the second parameter is the observed object (that is from which we want to receive notifications); and the third parameter is the message from which we are interested in receiving the notifications by the observed object.</p>
<p>Write the following code on the Code Editor associated for this method:</p>
<pre>dim observedObjects as xojo.Core.Dictionary = Objects.Lookup( observedObject, new xojo.core.Dictionary )
dim messages() as NotificationReceiver
if observedObjects.HasKey( message ) then messages = observedObjects.Value( message )
messages.Append sourceControl
observedObjects.Value( message) = messages
objects.Value( observedObject ) = observedObjects</pre>
<h3>Sending Notifications</h3>
<p>Now is time to add to the class the method responsible to send the notifications to those objects interested in receiving them from any previously registered object. Insert a new method for the <strong>NotificationCenter</strong> class and use the following values in the associated Inspector:</p>
<ul>
<li><strong>Name:</strong> sendNotification</li>
<li><strong>Parameters:</strong> sourceObject as RectControl, message as text, value as Auto</li>
<li><strong>Scope:</strong> Public</li>
</ul>
<p>And the following code in the Code Editor associated with the method:</p>
<pre>dim observedObjects as xojo.Core.Dictionary = objects.Lookup(sourceObject, nil)
if observedObjects &lt;&gt; nil then
  dim sourceObjects() as NotificationReceiver
  if observedObjects.haskey(message) then sourceObjects = observedObjects.Value( message )
  for n as integer = 0 to sourceObjects.Ubound
    dim target as NotificationReceiver = sourceObjects(n)
    target.valueReceived( value, message )
  next
end if</pre>
<p>As you can see, the first parameter of the method is the control that wants to send a notification (second parameter) to all the possible registered objects, passing the value that such objects can be interested to receive for processing it (third parameter).</p>
<h3>Stop receiving Notifications</h3>
<p>However, it is probable that one object wants to stop receiving notifications from any previously registered control. For that, we need to add a new method to the NotificationCenter class using this values:</p>
<ul>
<li><strong>Name:</strong> RemoveObserver</li>
<li><strong>Parameters:</strong> sourceControl as NotificationReceiver</li>
</ul>
<p>And the following code on the associated Code Editor:</p>
<pre>for each observedObjects as xojo.Core.DictionaryEntry in objects
  dim d as xojo.Core.Dictionary = objects.Value(observedObjects.Key)
  for each messagesForObject as xojo.Core.DictionaryEntry in d
    dim sourceObjects() as NotificationReceiver = d.Value(messagesForObject.Key)
    for n as integer = sourceObjects.Ubound DownTo 0
      if sourceObjects(n) = sourceControl then sourceObjects.Remove(n)
    next
  next
next</pre>
<h3>Stop receiving some Notifications</h3>
<p>It may also be the case that one object wants to unsuscribe from the Notification Center to stop receiving just one particular notification. For that, add a new method and use the following values on the Inspector:</p>
<ul>
<li><strong>Name:</strong> removeObserverForMessage</li>
<li><strong>Parameters:</strong> sourceControl as NotificationReceiver, message as text</li>
</ul>
<p>And write the following code in the associated Code Editor:</p>
<pre>for each observedObjects as xojo.Core.DictionaryEntry in objects
  dim d as xojo.Core.Dictionary = objects.Value(observedObjects.Key)
  for each messagesForObject as xojo.Core.DictionaryEntry in d
    if messagesForObject.Key = message then
      dim sourceObjects() as NotificationReceiver = d.Value(messagesForObject.Key)
      for n as integer = sourceObjects.Ubound DownTo 0
        if sourceObjects(n) = sourceControl then sourceObjects.Remove(n)
      next
    end if
  next
next</pre>
<h2>One Class Interface that runs them all: NotificationReceiver</h2>
<p>Along the implementation of our Notification Center class we have seen several times the reference to the <strong>NotificationReceiver</strong> data type. This is what we are going to get our hands on next.</p>
<p>In fact this is a <strong>Class Interface;</strong> what means that it works as a &#8220;glue&#8221; in order that any object can implement their defined methods. This way the objects can be seen as their native class and also as an instance from <strong>NotificationReceiver</strong>, so they can be registered as observers on the Notification Center independently the native class they are based on.</p>
<p>Use <strong>Insert &gt; Class</strong> Interface to add a new Class Interface to the project. Next, write the following values in the associated Inspector:</p>
<ul>
<li><strong>Name:</strong> NotificationReceiver</li>
</ul>
<p>With the Class Interface still selected in the Navigator, add a new method using the following signature in the Inspector:</p>
<ul>
<li><strong>Method Name:</strong> valueReceived</li>
<li><strong>Parameters:</strong> value as Auto, message as Text</li>
</ul>
<p>Done! Depending on your own needs, you can add more methods for the interface class in combination with the Notification Center class itself.</p>
<h2>Testing the Notification Center</h2>
<p>Now it is time to design the user interface in order to test the Notification Center class. The changes made on a <strong>TextField</strong> control will automatically update the contents of a <strong>Label</strong> control, a <strong>Slider</strong> control, a <strong>ListBox</strong> control and a <strong>Canvas</strong> control. Moreover, the Label instance will subscribe in the Notification Center to receive two types of notifications, changing his behaviour (the text shown) based on the received notification.</p>
<p>We will also add a couple of <strong>CheckBox</strong> controls to test the functionality to unsuscribe the Label control from all or just some notifications.</p>
<p>But before we start with that, and as we have seen in the previous step, we need that all the objects that want to be able to register on the Notification Center be of the <strong>NotificationReceiver</strong> data type. That means that we need to create our own subclases for the Label, Slider, ListBox and Canvas controles. Let&#8217;s start with the Label!</p>
<h3>Label Subclass</h3>
<p>Create a new sublcass for the Label Class. You can do that selecting the Label control from the <strong>Library</strong> and choosing the &#8220;New Subclass&#8221; option from the contextual menu; or you can drag and drop the control from the Library to the Navigator. Anyway, the result will be the same: you will have created a new subclass with the name &#8220;CustomLabel&#8221; (it can vary, depending the Xojo release you use). By the way, you also can use <strong>Insert &gt; Class</strong> in order to create a new subclass.</p>
<p>Regardless of the method used to create the new subclass, choose it in the Navigator and use this values in the associated Inspector:</p>
<ul>
<li><strong>Name:</strong> MyLabel</li>
<li><strong>Super:</strong> Label // This way, our sublcass will inherit all the methods, events and properties from the base class.</li>
<li><strong>Interfaces:</strong> Click on the button and choose &#8220;NotificationReceived&#8221; from the resulting panel/Window. Confirm the selection clicking on the &#8220;OK&#8221; button.</li>
</ul>
<p>As result of the last action, Xojo will automatically added the ValueReceived method to the class. Write the following code in the associated Code Editor:</p>
<pre>RaiseEvent newValueReceived value, message</pre>
<p>Here we raise a new event (not defined yet), so every instance from the class can be in charge of implement the real behavior in base of the parameters received.</p>
<p>So, with the &#8220;MyLabel&#8221; class still selected, use <strong>Insert &gt; Event Definition</strong> to add the event definition we need. Use the following values in the associated Inspector:</p>
<ul>
<li><strong>Event Name:</strong> newValueReceived</li>
<li><strong>Parameters:</strong> value as auto, message as Text</li>
</ul>
<h3>Slider Subclass</h3>
<p>Add a new subclass and use these values in the associated Inspector:</p>
<ul>
<li><strong>Name:</strong> MySlider</li>
<li><strong>Super:</strong> Slider</li>
<li><strong>Interfaces:</strong> Add the NotificationReceiver Class Interface as seen in the previous step.</li>
</ul>
<p>Write the following code for the ValueReceived method:</p>
<pre>RaiseEvent newValueReceived val(value)</pre>
<p>And add the event definition using <strong>Insert &gt; Event Definition</strong>, as we have seen in the previous step. Use this signature in the Inspector:</p>
<ul>
<li><strong>Event Name:</strong> newValueReceived</li>
<li><strong>Parameters:</strong> value as integer</li>
</ul>
<h3>ListBox Subclass</h3>
<p>Let&#8217;s create now the subclass for the ListBox, following basically the same steps already done with the previous subclasses. Use the following values:</p>
<ul>
<li><strong>Name:</strong> MyListBox</li>
<li><strong>Super:</strong> ListBox</li>
<li><strong>Interfaces:</strong> NotificationReceiver</li>
</ul>
<p>Write the following code in the Code Editor associated with the ValueReceived method added by the Class Interface:</p>
<pre>RaiseEvent newValueReceived val(value)</pre>
<p>And add the corresponding Event Definition using this signature:</p>
<ul>
<li><strong>Event Name:</strong> newValueReceived</li>
<li><strong>Parameters:</strong> value as integer</li>
</ul>
<h3>Canvas Subclass</h3>
<p>We have arrived to the last subclass definition for our example project. Add a new subclass to the project and use this values in the associated Inspector:</p>
<ul>
<li><strong>Name:</strong> MyCanvas</li>
<li><strong>Super:</strong> Canvas</li>
<li><strong>Interfaces:</strong> NotificationReceiver</li>
</ul>
<p>Write the following code for the ValueReceived method:</p>
<pre>dim s as string = value
newValue = s.ToText
me.Refresh</pre>
<p>Next, use <strong>Insert &gt; Event Handler</strong> to add the Paint event to the subclass. Write this code in the associated Code Editor:</p>
<pre>dim size as integer = val(newValue)
g.TextSize = size
dim centerx as integer = g.Width/2 - g.StringWidth(newValue)/2
dim centery as integer = g.Height/2+g.StringHeight(newValue,g.Width)/2
g.ForeColor = rgb(size, size, size)
g.FillRect(0,0,g.Width,g.Height)
g.ForeColor = if(size &lt;= 50, rgb(255,255,255), rgb(0,0,0))
g.DrawString(newValue,centerx,centery)</pre>
<p>Lastly, add a new property to the subclass using <strong>Insert &gt; Property</strong>, and using this values:</p>
<ul>
<li><strong>Name:</strong> newValue</li>
<li><strong>Type:</strong> Text</li>
<li><strong>Scope:</strong> Private</li>
</ul>
<h2>Designing the User Interface</h2>
<p>Once we have created the subclasses for the Controls we will use as observers in our example app, it is time to design the user interface. For that, choose the window by default for the project (Window1).</p>
<p>Xojo will show the <strong>Layout Designer</strong> for the selected Window. Drag the subclass controls from the Navigator (or from the Library) so they are arranged as shown in this picture. In addition, drag a couple of CheckBox controls and one TextField too from the Library to the layout.</p>
<p><img decoding="async" class="alignnone size-full wp-image-2073" src="https://blog.xojo.com/wp-content/uploads/2016/11/Captura-de-pantalla-2016-11-10-a-las-13.23.55.png" alt="captura-de-pantalla-2016-11-10-a-las-13-23-55" width="910" height="534" /></p>
<p>Choose the label instance (with the name &#8220;Label2&#8221; in the example project) and use <strong>Insert &gt; Event Handler</strong> to add the &#8220;newValueReceived&#8221; event handler previously defined in our class. Write the following code in the associated Code Editor:</p>
<pre>dim s as string = value
Select case message
  case "valueChanged"
    me.Text = "Value on source Control: "+ s
  case "charValue"
    me.Text = "ASCII Code for last keystroke: "+ str(asc(s))
End Select</pre>
<p>As you can see, the event uses the received message to decide how to work with the value sent by the observed object. In one case it will show the value as is, and for the other it will show the ASCII code for the value received as Text.</p>
<p>Select now the Slider instance (with the name &#8220;Slider1&#8221; in the example project), and repeat the action to add the Event Handler &#8220;newValueReceived&#8221; to the control. Write the following code in the associated Code Editor:</p>
<pre>me.Value = value</pre>
<p>In this case, the control will simply assign to his &#8220;value&#8221; property the value received.</p>
<p>Select now the ListBox instance (&#8220;ListBox1&#8221; in the example project). Add the Event Handler &#8220;newValueReceived&#8221; and write this line of code:</p>
<pre>me.ListIndex = value</pre>
<p>We will also add the &#8220;Open&#8221; Event Handler, so we can populate some default values to use in the example. Once we&#8217;ve added this event, write the following code in the associated Code Editor:</p>
<pre>for n as integer = 0 to 99
  me.AddRow str(n)
next</pre>
<p>Lastly, select the TextField instance (&#8220;TextField1&#8221; in the example project), and add the &#8220;Keydown&#8221; and &#8220;Lost Focus&#8221; Event Handlers. Once added, select the <strong>KeyDown</strong> event handler and write the following code:</p>
<pre>dim myNotificationCenter as NotificationCenter = NotificationCenter.sharedInstance
myNotificationCenter.sendNotification(me,"charValue",key)</pre>
<p>Next, select the <strong>LostFocus</strong> event and writhe the following code:</p>
<pre>dim myNotificationCenter as NotificationCenter = NotificationCenter.sharedInstance
mynotificationcenter.sendNotification(me,"valueChanged",me.Text)</pre>
<p>For both cases, we retrieve the shared instance from the Notification Center class and publish a new notification, passing along the own control as first argument (acting as originator), the message or published notification as second argument, and the value sent as the third argument. From this point on, the Notification Center will be in charge of propagate the received notification to all the interested objects.</p>
<h3>Subscribing and Unsubscribing to Notifications</h3>
<p>Let&#8217;s get in charge of the user interface controls whose function is to enable and disable the notifications for our MyLabel instance (Label1).</p>
<p>Select the <strong>CheckBox1</strong> control, add the Action event handler and write the following code in the associated Code Editor:</p>
<pre>dim miNotificationCenter as NotificationCenter = NotificationCenter.sharedInstance
select case me.Value
  case true
    miNotificationCenter.register(Label2,TextField1, "valueChanged")
    miNotificationCenter.register(Label2, TextField1, "charValue")
  case False
    miNotificationCenter.removeObserver(Label2)
    CheckBox2.value = false
end select</pre>
<p>Select now the <strong>CheckBox2</strong> control, add the Action event handler and write the following code:</p>
<pre>dim miNotificationCenter as NotificationCenter = NotificationCenter.sharedInstance
select case me.Value
  case true
    miNotificationCenter.register(Label2,TextField1, "valueChanged")
  case False
    miNotificationCenter.removeObserverForMessage(Label2,"valueChanged")
end select</pre>
<p>As you can see, in the first block of code we register the &#8220;Label2&#8221; control so it can receive both notifications when the checkbox value is <strong>True</strong>, and unsubscribe the control from receiving any notification when the checkbox is <strong>False</strong>. For the second block of code, the &#8220;Label2&#8221; control just subscribe or unsubscribe for one of the two notifications, respectively.</p>
<h2>Starting engines!</h2>
<p>What we need to put all to work? Add the <strong>Open</strong> event handler to &#8220;Window1&#8221; and write the following code.</p>
<pre>dim miNotificationCenter as NotificationCenter = NotificationCenter.sharedInstance
miNotificationCenter.register(Label2,TextField1, "valueChanged")
miNotificationCenter.register(Label2, TextField1, "charValue")
miNotificationCenter.register(Listbox1,TextField1, "valueChanged")
miNotificationCenter.register(Slider1,TextField1, "valueChanged")
miNotificationCenter.register(canvas1,TextField1, "valueChanged")</pre>
<p>This code will register the interested controls (observers) to the Notification Center for those Notifications they are interested in. Of course, this can also be done inside the Open event handler for every interested control!</p>
<h2>In brief</h2>
<p>As we have seen, with the combination of the <strong>Observer</strong> and <strong>Singleton</strong> Design Patterns, and the help of one <strong>Class Interface</strong> definition, we have created our own Notification Center from scratch to greatly automatice and simplify the communication between the objects, their processes and easying also the maintenance and extension of the app functionallity.</p>
<p>You can watch <a href="https://youtu.be/bCsGtHKM5GA">the video</a> (in Spanish only) that talks you though this example.</p>
<p><em>Javier Rodri­guez has been the Xojo Spanish Evangelist since 2008, he’s also a Developer, Consultant and Trainer who has used Xojo since 1998. He is in charge of <a href="http://www.aprendexojo.com">AprendeXojo.com</a> and the developer behind the GuancheMOS plug-in for Xojo Developers and the Snippery app, among others.</em></p>
<p>*<a href="http://www.aprendexojo.com/2016/11/patrones-de-diseno-observer-y-ii/">Read this post in Spanish</a></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
