VisualWorks users: rejoice! You can skip this discussion. Visual Smalltalk and VisualAge/IBM Smalltalk users: welcome to the border between Smalltalk and host resources. Traditionally in these latter two environments, if you use an object that allocates host resources of any kind, you must explicitly release those objects when you are done with them. If you don’t, the Smalltalk garbage collector will collect them when they are no longer referenced, but the resources will not be freed. The result is that your limited resources under your host windowing system will slowly degrade.One way to do deal with the problem is simply to send the message release to each GO when it is no longer referenced and will be garbage-collected, typically before you close your window or when you delete a GO. Visual Smalltalk 3.x provides an easier way to get the same effect via finalization. If you send an object the message needsFinalization, the virtual machine will cause the object to receive a finalize message just before it is to be garbage collected; i.e., when nobody references it any longer.In GF/ST under Visual Smalltalk and VisualAge/IBM Smalltalk, we have chosen to make use of finalization the default when you create new instances of GFGraphicObject. However, for finalization to work in Visual Smalltalk versions prior to 3.1 (it is included by default in 3.1), you must have the finalization “extra“ provided by Visual Smalltalk loaded into your image. If you don’t, GF/ST will still work without errors (since we handle the DoesNotUnderstand exception when we tell a GO it needsFinalization). However, you will then have to release GO’s manually. We highly recommend that you load the finalization extra when using GF/ST. Finalization is available in the \EXTRAS\FINALIZE subdirectory in the Visual Smalltalk 3.0 release.We implement a default finalize in GFGraphicObject that says:We can therefore be sure that every nodeGO will receive the message finalize, resulting in the release of host window system resources, when it is no longer held onto by anybody.Warning: If you do not use finalization under Visual Smalltalk 3.0.x, you must explicitly release your GO’s that use bitmaps (GFImageGO, GFGroupGO, GFButtonGO, and any of the Visual Inspector object GO’s). In addition, you should either use an unbounded stack for undo’s (the default is 15) or turn the option off via noUndo. The reason is that the GFBoundedStack holds onto instances of GFMemento in order to undo deletion operations you might perform. If undo is enabled, you should not release GO’s when you delete them, because an undo might cause it to come back. And, since you can’t release it when you delete one, if the stack is bounded, it is possible that the GO will be garbage collected when the stack grows, without your having released it. If you use finalization, this problem goes away. If you do not use finalization for some reason, you may want to consider making an unbounded stack or “no undo” be the default.You can create group and composite GO’s using the graphicObjects: method, supplying a collection of any GO’s as an argument. The following script illustrates the process. Also, refer to “Creating a GO in the Network Editor“ as an example of a simple GFGroupGO.Locators are required when you use dependent GO’s. Dependent line type GO’s we supply include GFDependentLineGO and GFDependentOrthogonalPathGO. You may use locators if you specialize handle behavior, too. See the discussions in “GFLocator“ and “Specializing Handles in the Network Editor“. For another example of dependent line usage, see the PsiSolid class used in the 3-D Figures demo, discussed in “Dependent Lines“.When you send the locator the message evaluate or asPoint, it will return the result of sending the message center to the polyline, aGO. Any message understood by the polyline is acceptable, as long as it returns a Point.This last expression will locate the first point in the polyline. It would only be useful with polylines, because all GO’s do not understand point:. This particular locator would be used to specify the location of a handle at a particular point on a polyline.There is a set of common protocol in GFGraphicObject to return points at specific locations in GO’s. Specific GO’s extend or override the protocol, as in the point: method of GFPolylineGO. Common protocol that all GO’s understand includes:
on: aGO
at: #offCenter:
with: 5@5
change: #translateBy:.An more elaborate very useful approach is to use a sense selector to compute a point from the mouse movement delta, and pass that result as an argument to the change selector. The protocol is:To take some action when a handle is invoked, you can handle the event #handleInvoked, which is triggered by the GFDrawingInterface.Whenever a GO needs handles (i.e., whenever it is selected), it triggers the event #generateHandles. If you do not handle the event, you will get the default set of handles for the GO. The default handles will work fine for initial development of an application, but they are almost guaranteed to be inappropriate for your end application. To specify the handles that are appropriate for your application’s GO’s, write a method that returns a collection of handles:Often, the state of an application determines what handles are appropriate. Also, since handles have so much behavior themselves, you may need to decide in your application logic what events handles will be handling, and what kinds of actions they will invoke. The typical way to deal with the problem is to write a handlesFor: method in your application. Then, when you create the GO, simply tell it:A position handle is the handle that is created when a GO is to be moved. While position handles are primarily used to move a GO, you may find other uses for them in your application. For example, you may want to send some message to another object whenever you let go of a the GO you are positioning. In that case, you could create the GFPositionHandle in a positionHandleFor: method in your application, and specify the releaseAction for it when you create the handle:Events are central to GF/ST architecture, so you’ll be using them a lot whether you know it or not. Refer to “The GF/ST Event Model“ for more information on the basics of events. If you want to know when or why an event is triggered, refer to “Events Explained“ in the “Class Hierarchy, Protocol, and Events“ section. In this section, we’ll try to anticipate some of the questions you might have about events when you start developing an application using GF/ST.We’re all used to looking at senders and implementors to track how messages flow through Smalltalk. When you use events, an event may be triggered in a method whose name is different than the event name, and it may result in execution of a method that is different than the event name. Consider the case when you use the #getMenu event to be able to provide your own menu to your drawing.If you look for implementors of getMenu, you will find that nobody implements it. When you look for senders of getMenu, you will find the methods that trigger the event. These methods are not sending the message getMenu, they are sending the message triggerEvent:, with #getMenu as the argument. Fortunately, “senders” locates all methods that use the symbol #getMenu.If you look at senders of networkMenu , you’ll only find the method where you set up the dependency; i.e., the method that does the when:send:to:. Let’s take a look at the #getMenu event to see what’s really happening. We’ll use VisualWorks as our example, although you’ll see similar results elsewhere.Examining senders of getMenu, we see the only interesting case is the menu method in GFGraphicObject:Now, if you put a halt in your networkMenu method, this is the stack you’ll see:
| 
     Copyright © 2005, 2014 Instantiations, Inc. All rights reserved.
        |   |