We’ve seen that the IDE provides three ways of editing an interface element such as a window or a control: the Properties Window, the Window Editor, and the Code Editor. In this section, we’ll pause to clarify the relationship between them. Figure 1-10 provides a schematization of the relationship between the three editors and the values of object properties. The rest of this section explains in words what the figure is trying to show in pictures.
The Window Editor and the Properties Window edit exactly the same thing—an entity’s predefined properties. They simply visualize those properties in two different ways. The Window Editor offers a physical representation of a subset of the very same information that is represented through name-value pairs in the Properties Window.
Consider, for instance, a window that contains a button. In the window’s Window Editor, it is evident that the window has a certain size and a certain title. But this information is also present among the values in the window’s Properties Window, as its Width, Height, and Title properties. Similarly, the Window Editor shows the button as having a certain position and size, and a certain caption in a certain font; and again, this same information is also represented in the values in the button’s Properties Window, as its Left, Top, Width, Height, Caption, and Font properties. But the Properties Window also lists some properties that have no physical representation in the Window Editor, or which cannot be edited there, such as the window’s Placement property, or the button’s Enabled property.
When you set the values of an object’s properties in the Window Editor or the Properties Window , what you’re setting are the values that those properties will have just at the moment the object first comes into being in the running application. For example, when you start up our sample application with the window containing a button, the window appears immediately, and that’s the moment those objects first come into being, so that’s the moment when the properties of those objects take on the values you previously set in the Window Editor and the Properties Window.
But after that, as your application continues to run, those properties could change. We’ve all seen buttons, for example, that change their caption. Think of an application that connects to the Internet; it might have a Connect button, which, once the user clicks it to make the connection, changes to read Disconnect, so that the user knows to click the same button to break the connection. Clearly, to accomplish the same thing in a REALbasic application, you’d need to change the value of the button’s Caption property.
How would you change it? Clearly not in the Window Editor or the Properties Window; those merely set the initial value of the button’s Caption property. Once the application is running, everything that happens is determined by its code; so it’s the code, which you write in the Code Editor, which must see to it that the button’s Caption property is changed at the appropriate moment. For the most part, REALbasic code has access to all the same object properties that you have access to in the IDE; it can examine them, and it can change them. So, in the Window Editor and the Properties Window, you initialize your object properties, that is, you state what their values are to be at the moment they come into existence; in the Code Editor you write instructions for what you want done with those values after that. In a nutshell: the IDE proposes, the application disposes.
beep msgBox "Sorry, this application doesn't do much!" pushbutton1.caption = "Push Me Again"
You might wish to increase the button’s width as well, so the new longer caption will be legible. Build and run the application, press the button, and you’ll see the button change its caption. This line:
pushbutton1.caption = "Push Me Again"
uses the assignment operator, which looks like an equals sign, to alter the Caption property of the PushButton whose name is PushButton1. In effect, the code has done, some way into the running of the program, the very same thing we were doing by typing into the Caption value of the button’s Properties Window in the IDE. Before the application started running, the settings we made in the IDE were in charge; once the application was actually running, the code was in charge, and was able to alter what we had done in the IDE.
Actually, it isn’t just code that may change an object’s properties as the application runs; in certain cases the user can do so, too. For example, when the user types in an editable text field (an EditField), its Text property is altered. Part of what makes writing a good application difficult (or fun, depending on your point of view) is that you cannot know in advance just what the user will do at any given moment, so you must try to prepare your code for any contingency.
The Properties Window also lets you set some properties that the running code cannot subsequently access. We may think of these as invariant properties of the object. Technically, these are not properties of the object at all; they are a completely different kind of feature of an entity. But since they are listed in the Properties Window, I have coined the term “invariant property.” (We’ll just have to hope no computer science majors are watching.) The invariant properties are the ones that appear at the top of the Properties Window, under the ID heading.
The most important invariant property is the object’s Name. Note that this is not necessarily the same as any label the user will ever see; the name of a button is not its caption (the text that appears within it), and the name of a window is not its title (the text that appears in its titlebar). Rather, the name is the identifier that the code will use to refer to the object. The code can’t change that name, because the object’s identifier needs to be unambiguous and unique, at all moments and in every handler, while the application is running. But you can change the name, in the IDE; and you should feel free to do so, in such a way as to make coding easier. In particular, you may well find that names descriptive of objects’ functionality contribute to more understandable and maintainable code.
For example, the button referred to in the code fragment from the previous section is called PushButton1, because this is the name assigned to the button when it was initially created in the Window Editor; but clearly this is not a particularly descriptive name, so you might rename it UselessButton. To do so, you would select the button in the Window Editor, and alter the Name value in the Properties Window. Your code can use the new name to refer to the button; indeed, it must do so—the code as it stands no longer works; if you’ve changed the button’s name, you’ll need to change its Action handler code to match:
beep msgBox "Sorry, this application doesn't do much!" uselessButton.caption = "Push Me Again"
There is no button called PushButton1 any more; instead, that button’s name is UselessButton. So you must refer to it in code as UselessButton, not as PushButton1.
Not only controls in Window Editors, such as our button, but also all project file components listed in the Project Window (except for the Menu) are objects with a Name property that can be changed through the Properties Window. For example, if you add a folder to your Project Window, it is initially called Folder1 or Folder2 or some such; that’s not very helpful when the purpose of a folder is to group project components meaningfully. Similarly, project components pointing to external files are initially given a name derived from the name of the external file; that name might not be useful when we come to refer to the project component in code, so you might wish to change it. When you select a listing in the Project Window, its name appears as the Name value in the Properties Window, and you can select and change that value. This action is so common that there’s a shortcut: select a listing in the Project Window and hit the Tab key, and the Name value in the Properties Window is selected, ready for you to type a new name; then hit Return to make it “set.” (Unfortunately, there is no parallel shortcut for renaming an object in a Window Editor; hitting Tab in that case selects a different object.) If you’d like to test this in our example project, try changing the name of Window1 to MainWindow.
As we saw when changing the name of PushButton1 to UselessButton, object name changes do not propagate automatically through code. After changing an object’s name, it is up to you to change any existing code references to that object manually from the old name to the new. The Find dialog can be a big help here. Even better, if you’re going to change an object’s name, try to do so before you’ve written any code that refers to it. On the other hand, object name changes do propagate through the physical part of the IDE. For example, if you make the changes described earlier in this section, the main window is immediately listed in the Project Window and in the titlebar of its own Code Editor as MainWindow, and the button is listed in the MainWindow Code Editor as UselessButton.
Do not assign a name containing a space to a picture or other external file listed in the Project Window; the Properties Window will permit you to do this, but this should be considered a bug, because afterward your code will be unable to refer to the object. In general, make sure that names contain no spaces, that they start with a letter, not a number, and that they are unique. REALbasic ought to help you with this, but it doesn’t.