3: check your controls

create some graphical stuff

Because we created a windows application we’ve got a gui already. And because of Visual Studio’s rapid application development technique, we can drag ‘n drop our controls easily on our form. Right click at your MainWindow- class (consider renaming it) and select View Designer:

zz4461a3a8.png

What we need for our application is: A combobox for selecting the IP and a textbox were we can put in a integer value for the port. With these two things we’re able to specify the endpoint the server listends on. Two trackbars will show the pitch and roll of our plane, two textboxes will show altitude and speed. Furthermore we need some Labels to give this application the final touch and we need some Buttons to start the server, shut down the application and so on. My gui is shown in the next picture:

gui1.png

Let’s look at some code:

delegate.png

As you can see I named our mainform FgfsMainForm. It’s a partial class. In .NET 2.0 by partial classes it’s possible to seperate the whole graphic stuff from your logic. Keep in mind that the graphical presentation and the logic which is behinde those controls are still thightly coupled, but regarding the overview you gain in your IDE while coding partial classes are a great benefit! And while we’re talking about thight coupling: Ever heard of the observer pattern?! It’s the great something I mentioned in the overview graphic on page two. Let’s go for the definition:

The observer pattern let’s you model a one-to-many relationship between objects. The nice thing about it: Neither the object which will be observed nor the observing objects have to know about each other. Now tell me: Don’t you think THAT IS loose coupling.

So, what the heck…? We’re having a DataObject. This object will take the incoming data from FlightGear. But FlightGear is sending data continously, so the DataObject is updated rapidly. How do we tell our Controls (e.g. the trackbars) to show what has changed? Let them fetch every sometime data from the DataObject (=do some polling)? Why don’t we let the DataObject tell them that data was changed? That’s what the observer pattern is for. And the next nice thing is: The DataObject doesn’t have to care of what type the object it’s telling its change is. For this reason we’re coding against an interface! To build this kind of structure what we do need are at least four classes: Two interfaces, one subject (the one thing which is observed) and not less than on thing that’s interested in the subject. For now we know, that our interested thing is the MainWindow. Later we’re able to add more classes (e.g. the hardware-presentation thing or some sound output) by simply creating a class that implements the IObserver interface. Let’s look at the interfaces:

iobserveable.png

The code above is the interface the subject to observe implements. The subject has an ArrayList in which all objects that care about are listed. Furthermore there’s a method that enables the removal of an object that’s lost it’s interest. These two methods are giving us the possibility to influence which objects are updated at runtime!

The last method we have to implement in our concrete subject later is the NotifyObeservers()– method. We’ll fire it every time we want every observer in our list to mention, that something has changed.

Now, here’s the interface our observers have to implement:

iobserver1.png

Every observer has only two methods to implement. The UpdateObserver()– method picks up all data the observer is interested in. This method is called by the subject! How the obeserving object does update is left by itself. The same is true for DisplayData(). We can’t consider how every observer displays it’s data (graphically, over some sound output….).

After this very short excursion in the patterns world look at the MainForm- code above. There’s a delegate. Why the heck do we need this? We have a thread running the so-called server. But our gui is running in the main thread. If we would try to change something in the gui from a different thread, our program will throw an exception. Therefore the delegate checks if the thread changing our gui is the thread that was creating it. If not it does the dirty work and while the thread belongs to the gui-class, the thread is allowed to change the thread’s threads…got it? Good, here comes the code:

delegate1.png

With the invokeRequired()– Method checks if the thread trying to access whatever is allowed too. If not a new delegate is created in the else- branch which itself fires the method matching the delegate’s signature (in this case the UpdateObserver()– method). If the invoke– check fails, our method is called by the delegate et voilà, second our invoke- check is successful.

The DisplayData()– method is called:

zz41e9670b.png

The data in our local DataObject is written to our controls…that’s all! While updating the trackbars is the same for the vertical and horizontal one, there’s a method that handles it:

zz3bc647f8.png
The Minimum- / Maximum- properties can be set in the gui designer or in the other partial class by hand.

So, that’s all for now. I consider writing down some more detailed information if I’m asked too, because I believe when you look up the code at the end and play around with it, you’re able to understand it easily and turn it to something better! There are few lines of code for speech output and the fancy hardware control – I’ll write some lines about concerning the hardware thing later. For the sound- output some few steps will make it. I’ll drop you a concrete line/ screenshot when I fire up my windows next time, but to give you a hint: You need to reference (right-click in properties window, add reference) some com-object – they may have something like speech in their name. Look it up at codeproject or put the words speech’ & ‘c#’ in your favourite search engine. A last remark: I integrated the sound- and hardware- code pretty straight forward. Remember the observer thing above? Yep – it’s a didactic arrangement: You can implement these things the right way, to get the best learning results out of this little tutorial (hope that anybody has some benefit from the lines written…)

I’m thinking about playing ’round with blender and model a plane, which will follow the movements made by its FlightGear parent. Therefore I have to play with managed directX. I’ll drop the lines, when I’m done. But that’s the shiny future…For now:

Bye and happy coding!

One Response to “3: check your controls”

  1. PEter Says:

    #region usings
    using System;
    using System.Collections.Generic;
    using System.Text;
    #endregion

    namespace FgfsSharp
    {
    public interface IObsehinking about playing ’round with blender and model a plane, which will follow the movements made by its FlightGear parent. Therefore I have to play with managed directX.rvable
    {
    void RegisterObserver(IObserver observer);
    void RemoveObserver(IObserver observer);
    void NotifyObservers();
    }
    }

Leave a comment