On Jun 3, 2006, at 8:55 AM, Lisa Sawin wrote:

Excuse the cross-posting! I have a thread going on over at the forum and wanted to see if anyone who only reads the NUG had some insight for me. The thread is here:

http://forums.realsoftware.com/viewtopic.php?t=5122

To summarize what I'm looking for: I have an application which has a main window crowded with controls, methods, events--you name it. I'd like to resize and reposition the controls on it to bring it into MS UI compliance. My goal is for the project to wind up with two windows, one for Mac and one for Win32. That way I can move the controls around and keep track of the whole thing visually, instead of coding that in to a targeted subclass of the window. All of the code, however, I'd like to have in one place. This would include the code for the window's events, all of the controls' events and the methods themselves.

It's clear that some kind of interface for the window would be good so that my app can refer to the two windows by one type. It's also been suggested that I use a controller to hold all of the code and simply refer all events in the window to the controller. Is there any way to handle this without a controller, which still keeps all of the code in one place? Any other ideas on how to go about structuring this?


Perhaps the simplest solution would be to use one window. Add two methods, LayoutForMacOS and LayoutForWindows. In these methods, you resize and reposition the controls. Add a constructor to the window and call one of them before calling Super.Window; that way the controls will be positioned before any Open event handlers are called.

If you want to write separate window classes for MacOS and Windows (for ease of layout, perhaps), then you'll need to introduce some additional classes for delegation of event handling. Here's a way to do it without massive subclassing. Define a class CrowdedWindowEventHandler. Move all of the window methods to it. These methods should only be called from handlers, so you can make them private. Then start adding a bunch of public methods for event- handling --

HandleOpen(w as Window)
HandleClose(w as Window)
HandleEnableMenuItems(w as Window)
HandleOpen(b as BevelButton)
HandleAction(b as BevelButton)
HandleKeyDown(e as EditField, key as String) as Boolean
etc.

Passing a reference to the control or window removes the need for a circular reference.

Now drop an instance of CrowdedWindowEventHandler onto the window; call this widget EventHandler. Then go to each event handler in the window and call the corresponding handler --

Sub Open()
  EventHandler.HandleOpen me
End Sub

You can then implement window behavior as needed in the handler methods. If you need to get the state of other controls in a handler, that's certainly possible. You could do something like CrowdedWindow(b.Window).EditField1.Text. Casting is generally a code smell, but since CrowdedWindowEventHandler is auxiliary to CrowdedWindow, it's a reasonable thing to do in this case.

Although you have two window classes MacOSCrowdedWindow and WindowsCrowdedWindow, I'm assuming that the behavior is the same, and a CrowdedWindowEventHandler provides that behavior for both windows. You could extract the CrowdedWindowEventHandler interface into a WindowEventHandler interface, and have CrowdedWindowEventHandler implement it if you later need to do so. And you could define an abstract class that implements the interface by forwarding the method handling to events in subclasses.

If I may work in a plug -- in the next issue of RBD I have a column that discusses a similar scheme in the context of implementing a singleton ServerSocket object.

Charles Yeomans


_______________________________________________
Unsubscribe or switch delivery mode:
<http://www.realsoftware.com/support/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

Reply via email to