 Ta-ta-ta-ta-ta-ta-ta-ta-ta-ta-ta-ta-ta-ta-ta-ta-ta. Hello, everybody. Just in case you didn't notice, David Kunz was wearing a white shirt. I'm wearing a black t-shirt. He was talking about Java swing. I'm going to be talking about SWT, the dark side. Now, why is it the dark side, you ask me? Swing was created by Sun, Sun microsystems. Sun, you know, the lights. SWT was created by, can anybody name it? Eclipse. It's all about eclipsing the sun. So we have our differences. In fact, even my slides are going to be with a dark backdrop. So simplifying desktop development with Glimmer. So I thought David's talk was very interesting. I liked it. I liked him talking about monkey bars. In fact, most, so what do you guys think is the most popular programming language in the world right now? Can anybody name it? Java. There's a number of guesses. I would say Java's not far from that. However, what's nice about the open source community is each person would pick their own language. And that's why we're here. That's why we're all Ruby developers. We like Ruby. We're passionate about Ruby. So what's happening with the desktop development framework in Ruby is kind of the same. There's a number of development frameworks out there. And each has its own approach. And each has its own strategy. And that is fine. People have different mental models with dealing with things. Some people are more visual. Some people like to work more directly with code, more directly with HTML versus designing it in a WYSIWYG editor. So different people have different approaches to things. By the way, my title here says Journeyman Craftsman. AKA Senior Consultant, officially. So is anybody familiar with Craftsmanship? Optiva is a company that believes strongly in Craftsmanship and the model of Craftsmanship. We strongly encourage Apparentus Ship as well. And we regularly have people come in Apparentus at our office in Chicago. So that's why I have that title. And I'm proud of it. I mean Journeyman is basically, you know, I've been in software development for about six years. I'm always in Apparentus. I'm always learning something new. But at the same time, I'm on my journey now. So this is basically a better term to use at this conference, I would say, than a senior consultant with an official status. As far as the talk, I'm going to be introducing Glimmer, a new framework for desktop development with Ruby. I'm going to be going over the available widgets or controls that you can use in Glimmer. I'm going to show a Hello World example. I'm going to talk about how listeners, data binding, and some of the exciting technologies that Glimmer has and that I have not seen in any other framework. So in fact, they're probably the main reason behind Glimmer. And finally, I'm going to demonstrate the first game program to Glimmer. So let's start. So I've had about three years of development in Java of desktop applications, which is not very like most people have had web experience. I've mostly had desktop, and it's mostly been with Swing, the Swing library, which is the library that comes with Java. Some of the main issues I've had with it were actually native widget support. So when you build a Swing application and you run it on Windows or you run it on Linux, it has the same look and feel. But it does not match the look and feel of your native operating system. So what often happened is that clients or customers or users were thrown off by the user interface. For example, you would right click on a text box, and everybody knows that if you right click on a text box, you get the menu that tells you copy, paste, cut. With Swing, you don't get it automatically. You have to program it yourself. You have to do the heavy lifting yourself. So eventually, for the next two years after that, I ended up working on a project that used Eclipse SWT. What's nice about SWT is that it's a better fit if you want to target different operating systems, but also target their look and feel and make the app look as natural on them as possible while using a better language than, say, C or some lower level language. So two years ago, I got exposed to Ruby on Rails by a co-worker called Dave Hoover. He used to work at ThoughtWorks, and he joined Optiva about two years ago. I really like the language. I really like the simplicity. I love the philosophies behind Rails, like minimalism, convention over configuration, all of that stuff. And I was wondering, how can we bring that to desktop development with SWT, possibly? And that's where Glimmer was born. So the goals that I had was basically platform independence, that's a must, native widget support, industry strength, ease of use. Now, I went and surveyed the market at first. I wanted to see what libraries Ruby already has. And as David has mentioned before, there's a number of them actually. There's the TK that ships with Ruby, FXRuby, GTK, WXWidgets, Monkeybars, which we just saw, Shoes, Limelight. Now, each library has its own approach of dealing with the matter. They're all different solutions to the same problem. Except some of them, like TK, for example, TK is more kind of like swing, where you get a look and feel that doesn't match your native look and feel. GTK is slightly that way, but GTK also requires the GTK library. Each of them didn't necessarily match the goals that I had in here perfectly, or as much as I wanted to. Monkeybars comes very close, actually, and I appreciate the approach that's used in it. The only reason why I still thought of building Limmer is because I like WYSIWYG editors. I like designing GUIs with things like NetBeans. In fact, that's what I used with Swing in the past. At one point, though, you may always end up dropping to the code, and when you look at the code spit out by NetBeans, it's just Java code. It's not clean, easy-to-read Ruby code. That was my only thing about it. So eventually in the future, I'd like to be able to use a GUI that generates Ruby code, but the fact that I couldn't do this right now is the reason why I wanted to build Glimmer. Shoes has a different goal. Shoes, actually, and I'm not sure if Limelight has the same goals. Is the person behind Limelight here? Micah, by the way, sitting in the back is the guy who did Limelight, and I wouldn't be surprised if he gave a lightning talk about it tonight, but the goal behind Shoes and Limelight, and correct me if I'm wrong, is basically to build web-like applications on the desktop with much easier coding practices, meaning you don't have to deal with HTML and JavaScript, CSS, all of that in order to get something working. You have one language, it's just Ruby. So I also liked that, but that wasn't the goal behind Glimmer. Glimmer is more about building desktop applications for businesses and providing an easy, quick way for reusing your operating system widgets. So I don't necessarily, I'm not necessarily about changing the look and feel, I'm more about making the app look as native as possible on your OS. So Glimmer leverages SWT, works on different platforms, native widget support, it provides an ultra-light UI authoring DSL. So in order to author the user interfaces, it works pretty much like HTML. With HTML is like a domain-specific language for authoring user interfaces for the web. Rubyists have done things like Hamel for the web also, which is an even tighter DSL. Glimmer aims to be kind of like Hamel, except for desktop development. And the key is data binding. Data binding, I think, is the feature that I have not seen in any other framework, and it's the thing that enables you to write coding, Glimmer, following a pattern called MVP, which is a slight modification on the Smalltalk MVC. It's very close to it, but I would say it's a level beyond it. Martin Fowler have talked about it a number of times on his blog, so I'll be going over a variation of MVP that's used in Glimmer. Okay, so overview widgets. For those of you who have been living in Webland, most of their career, that's a typical Windows, at least, app. And with a typical Windows app, they have different widgets used. Each one of those things that you see on the screen is a widget. Text widget, label, radio, checkbox, pretty much similar to the web, not much different. Now with HTML, you use HTML tags to build those. With Swing SWT in these libraries, normally you would use Widgets, a widget library, to declare those. So a shell and SWT, for example, is the thing that, it's the whole window. It's the thing that goes around it. They call it the shell. Then you have a group. Group box is kind of like that one that says gender or job. Combo boxes, lift boxes, text, label, spinner, et cetera. Okay, so let's look at Hello World. Hello World is, you know, this is as simple as you can get with a desktop application. It really just has one label that says Hello World and then it has a title to the window that says SWT. So why do I not like code spit out by GUI builders right now or written in Java or written in any other language other than Ruby? That's kind of how the code reads. And if you write it in pure SWT, you end up with, so the code that's in orange is not even relevant to the design of the user interface. It's more like boilerplate work. The code in white is relevant, but it doesn't map in any way to the way, you have to read it very closely and focus on it to even map it to the user interface. So it's not easily mappable to the user interface. Basically it's creating a shell, setting the text to the shell. It's Java, so they use verbose setters, setting a layout and then adding a label and specifying that it goes under the shell and then sending the text on it. So what are our goals behind Glimmer to simplify that? So if we want to simplify that, what do we want? I always like to begin with the end of mind, like start requirements first and then build something as opposed to bottom up just because it ends up, the product ends up matching our expectation better that way. So we want it to be very concise and dry. The code has to be as concise as possible. It has to ask for the minimum info needed. I don't want any boilerplate work. Convention over configuration just like Rails, so if there's any things that you need to configure but 90% of the time they're configured a certain way, I'd like that to become a convention that's built into the framework. Finally, I'd like it to be as predictable as possible for existing SWT developers and that's more of a concern for SWT developers like me who would like to switch to using this library. So I don't want it to have, I don't want it to stray around too much from the SWT terminology. There you go, that's Glimmer. It's as simple as it gets. It's really just like HTML. We have a shell, the text is the property of the shell and the value of the text property is SWT. That was the title. And then it has a label and then the property of the label is text hello world. So what's nice about this is it maps so closely to the user interface that when you read the code you can kinda visualize what it does. Okay, listeners. Next thing you would want to deal with with a framework like this is listeners. So you could add listeners and it's pretty similar to how JavaScript listeners are hooked in HTML at least to one method of how to do it is if you have a text widget you can say on modify text meaning on modification the text validate the contact model or on focus loss meaning the user tabs out of the field save the model. So you may want to save fields right when people focus out with the button. Same thing, you know, on widget selected meaning I'm pressed up the button, delete the model because it's a delete button. Okay, let's do a demo. Let's go through something very quickly. Okay, so logging application. Okay, this app is very, very simple. It's really just two fields username, password and then login. So when you log in it actually clears the username and password and disables them as well. And it disables the login button and enables the log out button. When you log out it re-enables them and re-enables the login button. It's very simple app. That's just a quick demonstration of how listeners work. Now if you were to look at the code I'm using Aptana IDE by the way that's an Eclipse based IDE. So this leverages the SWT library as well. Hence the dark side, no net beans here. Okay, so if we look at the user interface code we have the shell, the shell has a label that says username and then a text field another label that says password the text field and then two buttons login and log out. This is data binding, I'll go over it next. I won't cover it now but here's an example of how the button had an on widget selected hook and when you select the log out button, when you click it, it calls presenter.logout. It delegates, it separates the logic into a model which is called presenter and it sends the presenter the task to log out layout. Okay, so SWT has this concept of layouts which is very similar to swing. Basically, inside the shell I placed a composite a composite is just a container that you can put widgets in and then I set its layout to a grid layout. So with that, a grid layout with two columns and the width of the columns are not equal. This is more of an SWT thing that you would get if you look at the SWT API but if we look at the application so if you notice we have a field here, field here, field here, it's kind of like a grid, one here, one here. So it's really a grid with two columns and as you declare the widgets one by one, they automatically fill in the slots. If you want a widget to take two slots, you can declare that in the widget. In fact, let's see if there's an example of that, there may be one already. It's called grid data. Actually there isn't in this one but there will be, there will be another example. Alrighty then, data binding. Why is data binding cool? So data binding is technology that enables you to sync the state that you see on the user interface on the view, meaning what the text, the text that the user types or the value of the checkbox that the user checked or whatever, two values on a model. As long as you can sync everything that you see on the view to a model, then you can have a model that's clean of any user interface code that has everything the user inputted into the view and everything that also will get outputted to the user and then you test drive the model. So the whole key of data binding is to facilitate test driving the code. At Optiva, we actually believe strongly in agile practices and one of the key ones is test driven development. So that was one of the reasons why we've used actually data binding with SWT in Java as well was for that reason is to basically enable test driving models and then slap the view on top of them. So that way the view is more like an HTML doesn't need necessarily testing. You could do accept test testing maybe but not unit testing. And then most of all the logic lives in the models. So how does it work? It's a variation on MVC. With MVC from Smalltalk, the original MVC, the view listens to the model, observes the model and then the controller meaning me pressing a button for example triggers the change on the model. So with the controller I could say something like to the model, I could go to the view, add some code that says observe the status property on the report model and report it on the screen on the view. So that way if the report says loading the view will show loading. So in order to do that we have the view observe the model and then in the controller I would do something like I would press the load button, load report and when I press load the load controller will actually change the status, will have the model change the status to loading and then the view which is observing the model should get notified because it's observer pattern and reflect that change on the screen. That was how Smalltalk originally did it. That's the reason why I like desktop development a lot over the web. On the web unfortunately you couldn't do that. That's the whole reason why on the web actions and a controller in Rails have to render the screen. So the controller is not only connecting to the model the controller has to talk to the view as well. On the desktop the controller doesn't have to talk to the view because the view can just observe the model and as changes happen to the model they automatically get reflected in the view. What's nice about that is your code ends up being very clean, very decoupled. Data binding takes it a level further. Data binding says how about we simplify it where if we don't think about it this way, how about we think about it more as syncing? I'm syncing the view with the model. So if I change the value in the text field I want it to automatically be in the model without me having to worry about the details of how it got there. I don't want to think about listeners. I don't want to add observers. I don't want to do any of that. I just want to tie them together and then if I change the model I want it to automatically show up on the view. So that's kind of what happened in the login example that I just showed. Well as I'm typing here, JSON for example, if it's using data binding, JSON is getting copied automatically to a variable called username on a model called login presenter for example. And then status which says logged out is data bound to the status property. So if you go back to the code so here what I'm saying is the text of the username instead of declaring it like here where I declare a static value I'm saying bind the text. This is like a DSL for data binding. I'm saying bind the text to the username property on the presenter. If we go and look at the presenter model which is declared over here log in presenter indeed it has a property called username. Now if for any reason here I do something like I log in I'm saying self.username equal empty meaning clear the username. And as you saw the moment I clicked logged in the username got cleared like magic. This is happening with data binding. So what's nice is in the model you write the code as if the view doesn't even exist. You can test drive it completely. Whatever happens on the model happens on the view. One demonstration that I like to show people that it's nice about this is the following. What if I bind these two text fields the username and the password to the same model property and then I start typing in the username. Can anybody guess what would happen? The other one changes. Exactly. Let's do this very quickly. So what I'm gonna do here gonna take the password fields. I'm gonna remove the password property from it so that it starts showing its output because it was hiding its output earlier. And then I'm gonna bind it to, whoops, username. And if I type here hello, you see. Basically gets copied automatically through data binding to the model and then gets copied back automatically to the other field. Okay, it's getting back here. Another demo of data binding. Data binding shows the strength the most and it saves you from writing the most code when dealing with tables. So tables and trees are very commonly dealt with in business applications. One of the applications we built which was deployed to 50,000 users was actually, it actually had about 10 tables, maybe 12 tables. So data binding was awesome at reducing the amount of work you have to do to display information on a table. So whether it's Sweng or SWT, you usually have to write a lot of boilerplate code. Sometimes Page is a boilerplate code to display that information on a table. Whereas if we follow the principles that we set with Glimmerer which is we want the minimum amount of input needed to display information on a table, then here's how it would work. So let me open this example, contact manager. So let me show you the example first. So this application basically is a contact manager. It shows you your contacts and then you can filter them. And then I would enter something like Frank. I would hit find. It would filter the list. Now, how do you bind this table to a model? Wastically, what you want to do is do two things. You want to bind what you're seeing in the rows to a collection of models. So each row represents a contact. So if you're doing object-oriented programming and we want to represent the contact object in a table, you need a collection of, the abstraction of a table is a collection of contact. So that's one binding that we need to do. Second binding is what are the columns that we want to show? So the contact may have a number of properties, name, address, email address, age, whatever. What are the properties we want to show? So basically, we then bind each one of those properties to one of the columns of the table. And that's it. That's the minimum amount of info you need. So if you look over here, here's the table. Here you declare the column headers. And then finally, you say the items of the table are bound to the results collection on a contact measure presenter. And the properties are bound in this order. They're gonna show up as last name, first name, and then email. That's exactly what we saw. So this one line of code is about, I'm not exaggerating, about 50 lines of code in Java. If not more, I wouldn't be surprised if it's more. And that's Java with data binding. If you're using Java without data binding, I think it's even more lines of code. It's actually classes and classes of things to get it done. Go ahead. I think there's more things like column sorting. Actually, this comes from SWT. You repeat the question. So the question that I said was, does Glimmer offer any sort of features for column sorting, like any built-in support for column sorting? This is a feature in SWT. And I believe you have to build it in yourself. And in the current state of Glimmer, I don't think we support it yet. In fact, let me verify. But eventually that would be a nice feature to have where you would, by default, they're sortable. Okay, so let's continue. Okay, test driving with MVP. So the whole reason we're using data binding is to facilitate test-driven development. What kind of process can you follow in order to do test-driven development with that model view presenter pattern? So let's first talk about presenters. What is a presenter? A presenter is a special kind of model that handles presentation details. So there's models that do the business logic, like, for example, logging a user out or retrieving contacts from a database. But then there's models that really are handling presentation details, meaning, what is the formatting of the data that we're gonna show to the user? Are we gonna be basically aggregating different pieces of data before we show them? Are we gonna, what happens if a user press this button? Does that disable the other two buttons? These are more presentation-level details. User interface details, I would say. They're not necessarily business logic. So what this pattern encourages is separating all that kind of logic into a presenter that reflects exactly what you see on the view, and then data bind them together. So then whatever happens on the view, on the user interface by the user, happens in the presenter, and then you can test drive the presenter. So the one rule of thumb for doing it is basically for every field that you see on the user interface, for every text field, for example, checkbox, whatever, you would have a property on the view. So as we saw, we saw a username, password, and status. You have username, password, and status on the presenter. Now for every action on the view, like a button, like a pressing a button, you would have a method on the presenter. Does that remind any of the Rails folks of something? It's pretty much like Rails controller actions. So whenever you press a button on the view, it'll get mapped to a method in the controller. That's almost exactly like how Rails handles it. Except this is the desktop way of doing it. So MVP is a variation on MVC, like I said earlier, and that leverages data binding. What it does is it basically, instead of tying the view to a model directly, it ties, it binds, it data binds a view to a presenter. So the controller that was used for data binding purposes is still a data binding controller, and it's only task is to data bind the two, meaning sync the two together, so that if changes happen here, they could copy it there vice versa. However, the difference is that the presenter is a special kind of model. It's not just any kind of model. So with MVP, you tie a model to the view that's encapsulating only presentation details, and it's hiding the business logic. So it's a layer on top of the business logic. So on the one hand, the presenter is basically a model. Now on the other hand, the presenter is a controller in the classical MVC sense, or more of the real sense, as in actions, when an action happens, the first method that's hit is on the presenter, meaning the presenter is the application there, and then the presenter delegates some of the work to the business models to get the work done. Does anybody have any questions before I move on? Okay, so one process to test drive desktop user interfaces easily is basically do the user interface first, assuming there's no presenters, there's nothing. It's kind of like designing your HTML first. See how it looks like, and then from that, you'll know exactly what presenter you need to reflect it. Once you have the test drive of the presenter that abstracts the user interface, and like I said before, for every UI field, you need a property, for every button, you need a method on the presenter. And then finally update the user interface code to data bind. So if you look at the code example, contact manager for example, as you see, so here's the user interface. It's a label that says first name, text field, label, text field, label, text field. Each text field is bound to this presenter. If we go and look at the presenter, the presenter is a completely different class, so let's go and look at it. And there's the presenter test. So if you go to the presenter test, find, specify all finds for one result. So the approach that I like to follow with testing, and there's many approaches, is the more the black box testing, as in you're testing against the public API. With this approach, you would basically, if you go back to here, so the fields were bound to first name, last name, and email on the presenter, and then the button is bound to the find method on the presenter. So if we look at the contact manager presenter, we have these three fields, first name, last name, and email, and then we have the find method. That's it. That exactly reflects what the view has. That exactly reflects what the user interface has. So if you look back at it here, the test is so clean now, because I'm working against the presenter, but I'm pretending I'm working against the view. And what's nice about that is I'm writing a test against the application layer, and then I can refactor my hardout under it. The models that serve whatever I'm testing here can be refactored in any way I'd like. So this is really just testing the, you know, if I poke at the presenter from the public API by setting the first name, last name, and email, like that, which is kind of like what the user does when they're interacting with the user interface. It's almost like writing a UI test. And I hit the find button. I want the results to be equal to this, that, and that. And same here, here. This is for two results. This is for no results, you know, exception case, et cetera. Initial results, when the table is first displayed, I don't want it to display anything. I want it to be empty. So as you write those tests, that kind of test drives this layer, which ended up with us having a contact repository model, which represents the database. This is an in-memory database right now. It's faked with a hash, but this could represent something, that could be a contact active record model, really. It's very similar. And it basically lets you find something within a collection. Any questions before I move on? Okay, now starts the fun part of the presentation. I'm gonna be showing, demoing a game. It's the first game written with this framework, except the condition for demonstrating that game is that everybody has to participate. In fact, I brought a goodie bag. Gonna be throwing some goodie bag, and I have pens, but that's dangerous. I've tried it before, and you don't want any pens right now. You can grab them for me later. But I have this ball for the winner, and then wristbands. Everybody wristbands like the latest craze nowadays, so. Okay, so, tic-tac-toe. I wanted to see how clean I can separate the models from the view in a game, and like something like tic-tac-toe. And I thought it worked beautifully with glimmer. I was able to destroy the logic completely in a very clean way that was completely separate from the view, and then talk the view on top of it. So if you were to represent this in OO design, with OO design, you would have a tic-tac-toe board, and then the board would have boxes, and then you can interact with the board and say mark this box X, or sorry, just mark this box. So that's really what the user does. If you think about it from the user's point of view, mark this, mark that. And then the board is smart enough. It has the business logic to handle figuring out whether it's gonna be an X or an O, and the board is smart enough to recognize that winning state and the moment the winning state is, or losing state or whatever is hit, it notifies its observers. So it needs to be observable as well in order to separate it from the view completely. Now, the views that layer on top of it with data binding and observes the models, and it mirrors exactly what's going on. So without further ado, let's start. Who wants to give me a first move? Okay, let's do center. Usually that works best. There we go. Next. Sorry? A corner. Which one? Oh, some kinder. Somebody help him get in that. I usually do it to a bowl. Now, middle. Middle way. There you go. Just grab that there. Next. Block. Sorry? Block. Middle. Left. Here. Okay. Next. The game there. Go, yeah. Next. Upper right, upper right. So are we winning today or are we losing? Are we drawing? No. Okay, I'll just throw this one into everyone's question. Awesome. So now the win for all of us is how does that work? How do we make it work? So let's look at the codes. Tic-tac-toe. So if we think about it conceptually at first, so let's just think conceptually how we want to model it because we're trying again with Glimmer to reflect your mental model as much as possible. We're writing the code. So if we look at the Tic-tac-toe board, what's the minimum amount of info you need to provide to that language in order to build it? You want to say, I want a shell, and then I want three columns and three rows of boxes. What's nice about, so the key thing about Glimmer is that not only is it declarative, but it's written in pure Ruby. That's the beauty of Ruby, is you can create internal DSLs, meaning a domain-specific language that's built within the syntax of the language so that you don't have to go outside the language and you can still use control structures like if statements, for loops, whatever. So if we go back to it, so I have a shell, it has a composite under it that has a grid layout with three columns of equal sizes. And then what I do is I iterate over from one to three and for each I'm gonna create a row and then again iterate and then for each I want a column. The only widget that's repeated in all of them is a button. That's really what it is. Now the button, I don't want it to do any of the heavy lifting, I don't want any logic in the button beyond data binding or listener code. So what do we do? We data bind the text value that shows up as an X or Y to the value of the box with the row number and column number on the model. Actually the sign property on it, the sign is X or O. Then we data bind the enablements. If you notice every time I hit a field that got disabled that's because you can also bind enablements of fields. So I bound whether the field is enabled or not the other property to whether the field is empty or not on the model. So if the field on the model has not been filled in with an X or an O and it's empty that gets reflected in the user interface. And then last but not least is basically simply on press of any button mark the box with the row number and column number that you pressed. So that's as easy as it gets. And if you look at the model, so we have a TikTok tool board that has those public methods and it was completely test driven by the way. If you look TikTok tool test. So TikTok tool board acted as the presenter for this case. In this case, we had a, this is a special case where the presenter was not only did it represent the representation model, it was also the real model. The business model. And this is where we write the test, you know, mark center X, mark center X, top center O, whatever. Different test cases, you know, till we cover everything. You know, wins top right to bottom left, blah, blah, complete test coverage actually. It has like 100% test coverage. So if we look at the box, the box really just saves its state. It can remember when you mark it, it can remember which sign you marked it with. With symbol, it can know if it's empty or not, stuff like that. So to recap, we've given an introduction about glimmer and why we want glimmer. It's basically a different approach. There's a lot of approaches. They can all live happily together. One approach is to use MVP pattern model view presenter. And there's nothing that could stop building a GUI builder on top of the glimmer syntax. But at least then you have a GUI builder that you can use sometimes. And if you ever had to drop to the GUI syntax to dry your code up or do extra special things, you would be working with Ruby code, not Java code. An overview of the widgets that are in the SWT library, hello world example, talked about listeners, which enable user interaction with the user interface. Data binding differences from MVC and then test driving with MVP. And finally we demoed a game written with glimmer with the clean separation of models from the view. So that's it everybody. Thank you very much. If you have any questions, let me know. Sure, go ahead. I noticed in your game that one of the boxes was always kind of selected as the default. The blue border around it. There's no way to get rid of that. Yeah, this is focus. What you are seeing is focus. And that's done for people that are physically challenged. They want to use the keyboard and not the mouse to be able to navigate the user interfaces. That's one of the nice things about SWT being native. It already supports that. So actually Swing supports it too. But SWT basically leverages whatever the OS has. So by default widgets have a focus in order to enable people to navigate by keyboard. But you can always hide it if you want. We're driving tests. This is something that I haven't thought too much about. But it's very neat. When you're using GUI builder tools, you're saying there's no reason you couldn't put it in a GUI builder tool. Prospects for testing of UIs and to build something out there that has something on them already. I mean one way you can attack the problem is. So the question is basically right now you can test drive the application using the presenter. And you can build the user interface by writing that syntax which is kind of like HTML. Or you can eventually in the future if we end up having a GUI builder, you can build it that way. The question is can we test drive the GUI with the unit test? Was that the question? Did I say it right? Or can you somehow test drive the GUI? And my answer for that is there's a number of approaches for it. You could take the Rails approach which is writing R-spec tests. So with R-spec for example, using cucumber, the story runner, you kind of hit the user interface from the user's point of view. That ends up test driving some of the GUI features. So you end up at least hitting some of the GUI to make sure that the data binding was correct for example, that I'm not data binding the user name to the passwords. Another way is to write Selenium tests. A third way and I've been researching that is coming up with the DSL for test driving user interfaces and ensuring that the data bindings are correct. That's still in research, it's not done yet. Go ahead. So how do you complement glimmer? How do you round it out for data storage and some core data and local storage and Adobe Air to kind of just to have all those same reasonable about the native limitations and things like that? I guess, what goes well with glimmer? So if I understand the question you're asking what are the methods of storage, data storage that you could use in glimmer? I'm just saying, just kind of rounding out the whole desktop application experience. It's like, okay, we got the, we have to find out all the widgets that are going to look nice on the Rows then if you're going to continue to develop a desktop app then what else goes well with it? What else would you do for data persistence between using your application? I can tell you an example from an experience in a project, the one that was deployed to 50,000 people. That one was not, that one was built SWT but it was built with Java. So it was a desktop application that enabled sales people to enter sales applications that they gathered from people, like sales calls basically. And then on their laptop without internet and then when they get home or get to the office and connect to the internet they can submit them. So it needed a database for sure and we just leveraged one of the databases that were available with Java, which is Hibernate. Later we switched to iBattice which was a different technology. However, in order to sync with the server, the server was kind of like a RESTful web service and then this was talking to the RESTful web service that's how it was pushing its data to the server and syncing both the server database and the client database. So I'm just giving you an example but I'm not sure if I hit on your point to be honest. Maybe we can talk about this. Sure. If we feed, so if you want more information about Glimmer. So I'm gonna be posting this on my blog soon. There's a number of articles about it. You can just Google Glimmer. I mean, that may be the easiest way but there's an article in InfoQ that's just an interview and then the nicest thing actually is this Glimmer Eclipse Zone introductory article. That's a great article for an introduction on how to use Glimmer for both Java and Ruby developers and it touches on both sides and what's nice about it is if you're not very familiar with SWT, it kind of references how you can look at the SWT API and map it to Ruby. So feel free to check that out. My blog is andymalay.blogspot.com. I'm gonna be posting a link there soon to download the slides. But for now, the project used to be on Ruby Forge so you can still check it out there but it's moving to Eclipse. It's becoming an official Eclipse project. So in fact, the code was just donated to Eclipse about a week ago. So it's gonna be, once it becomes an Eclipse, that would be the place to check it out but for now you can check it out on Ruby Forge. That's it. If you have any other questions, feel free to talk to me outside. Otherwise, have a good lunch, everybody.