Comments
bruce.armstrong wrote: Somebody just said it better than I did, and with more chops to say it: Open Letter to Mark Zuckerberg, Sheryl Sandberg & Facebook Mobile
Cloud Expo on Google News


2008 West
DIAMOND SPONSOR:
Data Direct
SOA, WOA and Cloud Computing: The New Frontier for Data Services
PLATINUM SPONSORS:
Red Hat
The Opening of Virtualization
GOLD SPONSORS:
Appsense
User Environment Management – The Third Layer of the Desktop
Cordys
Cloud Computing for Business Agility
EMC
CMIS: A Multi-Vendor Proposal for a Service-Based Content Management Interoperability Standard
Freedom OSS
Practical SOA” Max Yankelevich
Intel
Architecting an Enterprise Service Router (ESR) – A Cost-Effective Way to Scale SOA Across the Enterprise
Sensedia
Return on Assests: Bringing Visibility to your SOA Strategy
Symantec
Managing Hybrid Endpoint Environments
VMWare
Game-Changing Technology for Enterprise Clouds and Applications
Click For 2008 West
Event Webcasts

2008 West
PLATINUM SPONSORS:
Appcelerator
Get ‘Rich’ Quick: Rapid Prototyping for RIA with ZERO Server Code
Keynote Systems
Designing for and Managing Performance in the New Frontier of Rich Internet Applications
GOLD SPONSORS:
ICEsoft
How Can AJAX Improve Homeland Security?
Isomorphic
Beyond Widgets: What a RIA Platform Should Offer
Oracle
REAs: Rich Enterprise Applications
Click For 2008 Event Webcasts
SYS-CON.TV
Top Links You Must Click On


Organize Your GUI with Layout Managers
Getting control over your windows

PowerBuilder novices know the problem as well as seasoned PowerBuilder developers. You build a window in the window painter. You arrange the controls on the window and the layout looks fine.

Your users start the window and size it. It doesn't look fine any more because the components in the window don't fit the workspace. PowerBuilder doesn't resize automatically, so you have to build a resize service. The PowerBuilder window object delivers an event that resizes and positions the controls perfectly whenever the user resizes the window. But you have to code it yourself and adding controls expands the script in the resize event. Sure, you can implement it separately in functions, but you have to code it in all the windows you're using in your application. Copy and pasting is helpful, but a better way is to inherit the windows from a base window with a resize service implemented. To do this you have to program a generic resize service in the ancestor window. But not all your windows look the same, so you have to build different ancestors for different layouts. Another problem is how to change the layout without building a whole new window.

Let's have a look how other programming languages or frameworks solve this problem. Let's adapt some of ideas from Java or C# and build some layout managers.

What Is a Layout Manager?
The Java 2 Platform Specification says a layout manager "defines the interface for classes that know how to lay out containers." In other words, it's simply an object that does the resizing work for you. You tell the object which controls to lay out and start the layout process with a function. The way the objects are laid out depends on the layout style you specify in the manager. "Border," "grid," or "tab" are some of them and will be explained below. Layout managers can be used for different types of graphic objects like windows, tab folders, or custom visual user objects. The layout for an object can be done by changing the definition of the container in the constructor without building a new inheritance or changing the resize event. But unlike the resize service in the PFC where we have to define the resize behaviour of every object we register, with a layout manager we only have to register the objects. The layout is defined by the type of layout manager that we use. So setting up a layout is less work with layout managers.

Building a Layout Manager for PowerBuilder
Think of a PowerBuilder layout manager as a service class similar to those in the PFC. "All" we have to do with this service is to register the objects we want to resize automatically and specify the layout style. The different layout styles are based on different layout managers. So we have a kind of service-based architecture (SBA) instead of inheritance-based architecture.

That doesn't mean there's no inheritance in the layout manager architecture. All the objects for the special layout styles have common functionality that's implemented in a common base object.

We need an ancestor object for all layout managers that defines the base functionality as shown in Figure 1.


n_cst_layoutmanager inherited from nonvisualobject

The whole idea is to lay out the controls in a window or user object. So we need a function to do this. The function has to lay out the container and arranges the controls. The container could be a window or another control like a tab page. Both are descendents from the graphic object type, so my first thought was to use this class for the common function for all graphic objects. But I am afraid we can't use this class because a graphic object doesn't have information about the position and size of the object. So we have to write two different functions, one for the class window and one for drag objects. The drag object is the ancestor class of all the controls in a window that can be containers for other controls (group boxes or user objects, for example). If you want to use a layout manager to draw objects like rectangles and ovals you have to build more functions in the ancestor class for the draw object type and perhaps for the mdiclient too.

I chose to implement different functions for each container type to be sure that no wrong function calls are implemented because the compiler wouldn't accept them.

Let's have a look on how it's defined for a drag object:


public function of_LayoutContainer(readonly dragobject ado_parent)

If you've got two or more functions to lay out different types of visual objects, as described above, you can consolidate your work by implementing a protected function of_layout(readonly graphicobject ago_parent), which will do the layout work. This function will be internally called by the different of_layoutcontainer functions (maybe four as described above). Here is the implementation for the window:


public subroutine of_layoutcontainer (readonly window aw_parent);
this.of_layout(aw_parent)
end subroutine

This is done this way to be sure that no wrong function calls are implemented, because the compiler won't accept them and you only have to implement the functionality once per layout manager.

Notice that the function (of_layout) is a kind of virtual function in the n_cst_layoutmanager object, because all the layout managers we use are ultimately inherited from this base object. The function is coded in the descendants because this is the main function of the layout process and differs by type of layout manager.

It's now time to think about telling the object which components to arrange. We can do this, for example, in the constructor event of the container with a function like this:


public function of_addLayoutComponent
(string as_name, ref dragobject ado_component)

We store the components in an instance array (n_cst_component invo_component[]). To create this array we have to define the class for n_cst_component (see Figure 1) and a set of functions to make it work:

  • of_setComponent(ref dragobject ado_component): Defines a reference to the component that is treated as a private instance variable ido_component in the object.
  • of_setName(string as_name): Gives the component a corresponding speaking name treated as a private instance variable is_name in the object.
  • dragobject of_getcomponent(): To get a reference to the component from the instance variable ido_component.
  • string of_getname(): To get the name of the component from the instance variable is_name.
  • of_reset(): To delete all instance variables in the whole component.
The function of_addLayoutComponent should be implemented as follows:

long ll_counter

// Get the Maximum of the componentlist
ll_counter = upperbound(invo_component)

// and create a new component at the end
ll_counter++
invo_component[ll_counter] = create n_cst_component
invo_component[ll_counter].of_setname( as_name )
invo_component[ll_counter].of_setcomponent( ado_component )

To remove a component from the list you have to implement the this function:


//of_removeLayoutComponent(ref dragobject ado_component)
long ll_index, & ll_max
// search the component in the componentenarray
ll_max = upperbound(invo_component)
for ll_index = 1 to ll_max
if ado_component = invo_component[ll_index].of_getcomponent() then
// set the component to null
invo_component[ll_index].of_reset()
end if
next

This is the base functionality of a layout manager, but it doesn't lay out anything yet. You can tell it which components it should lay out for which container. The defined function of_Layout is only a virtual function. You have to implement it in the specific layout manager type.


About Christoph Menken
Christoph Menken is a senior developer and consultant on Power People (www.powerpeople.de) and a frequent speaker at the PowerBuilder User Group Germany (www.pbugg.de). He has been using PowerBuilder since version 5.0 and PocketBuilder since version 1.5.

In order to post a comment you need to be registered and logged in.

Register | Sign-in

Reader Feedback: Page 1 of 1

Enterprise Open Source Magazine Latest Stories . . .
Before embarking on using open source cloud technology for your web property, a basic understanding of cloud, as it’s used in the industry, is essential. While there might be exceptions, here are the definitions. A software application delivered on the web instead of installing standa...
Businesses today generate billions of events or 100s of TBs of data in a month. These data contain valuable insights into customer behavior, key trends, buying patterns, etc. If these are successfully mined, they can lead to successful decision-making to maximize revenue and traffic fo...
Grid Dynamics, an eCommerce technology solutions company, and GridGain Systems, makers of an open source in-memory platform for Big Data processing, on Wednesday announced the expansion of their partnership which began in 2008. Grid Dynamics provides personalization and big data solut...
Private clouds solve many problems for enterprises and bring unique operational challenges along with them. There are dozens of companies of all sizes that will build you a private cloud and turn over the keys – then what? Trying to convert a traditional enterprise IT operations team t...
The networking industry has gone through different waves over last 30+ years. In the ’80s, the first wave was all about connecting and sharing; how to connect a computer to other peripheral devices and other computers. There were many players who developed technology and services to ad...
If your organization already uses virtualized infrastructure, you are well on your way to providing IT as a Service. But as businesses demand faster results in today’s competitive market, organizations look to gain more benefits from cloud computing than just virtualized infrastructure...
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021


SYS-CON Featured Whitepapers
ADS BY GOOGLE