|
SYS-CON.TV Webcasts
Comments
Did you read today's front page stories & breaking news?
SYS-CON.TV
|
Top Links You Must Click On
DataWindows Wider is Better
Wider is Better
By: Joseph Slawsky
Jan. 1, 2002 12:00 AM
In the coding life of every programmer there's often a need to create a view of data that extends variably both to the right and vertically. Using a grid presentation style usually solves this problem. But what about when a programmer needs more control over presentation style? There are situations where the grid simply doesn't pack the graphical punch that you need when displaying data, and isn't suited for some situations the programmer will encounter. You could create a DataWindow with dozens of heading columns and manipulate them programmatically, but that would be a time-consuming solution to create and maintain, as well as limiting you forever to the number of columns you created when the window was first defined. We need the DataWindow to expand to the right with the flexibility of a grid and to possess the presentation flair that we rely on from other PowerBuilder DataWindow presentation styles. The solution is to create the DataWindow definition programmatically at runtime. That way we're able to adapt the DataWindow to the data. Using this technique requires some knowledge of the DataWindow syntax, but not as in-depth as you might expect. Although this method is slower to execute than its compiled DataWindow brother, the on-the-fly DataWindow possesses a flexibility that we can exploit for maximum graphical impact.
Using the Create Statement
The problem is that, until we retrieve the data, we don't know how wide to make the chart; furthermore, creating the headers would be a nightmare. Enter the DataWindow create statement. This statement dynamically creates a DataWindow from DataWindow syntax. In short, DataWindow syntax is the language that describes the DataWindow. The syntax is fairly complex, but when properly dealt with, you'll need to worry about only a small subset of the commands. The question is where best to begin - and for the answer we examine the DataWindow itself.
Getting Started
For the purposes of this demo, we're creating a DataWindow (see Figure 1) that has three standard column elements (label, start_date, and end_date) as well as a pseudographical element: a lime-green text box with a shadow box border, to give our Gantt line some character (see Figure 2). Notice how I've incorporated the standard columns, along with the gray elements, which will be repeated later in the process.
Design Is the Key
Design is the key here. You should shoot for creating the basic DataWindow structure and make the recurring elements (in this case the dates in the header) easy to identify. While you can redesign the DataWindow at any time, the syntax will become more entrenched in the code as time goes on. Save your DataWindow. Now you're almost ready to tackle the DataWindow syntax, but first we need to generate the syntax for the window you just created. Go to the library painter and highlight the DataWindow we just created. Right-click on the entry and select Export. A filename will be provided. Go ahead and open up the exported DataWindow in a text editor, because that's what the export is. You're now looking at a nongraphical representation of your DataWindow (see Figure 3). Notice that each line is really a composite of attributes of an element of your DataWindow. That's the key. As the exported syntax is no more than a grouping of element attributes, we can add additional elements at will - just by knowing what the attributes are for the element. The attributes in the example tell me such information as the x and y position of the element and what band the element appears in. The tricky part is identifying the portions of the syntax that we'll be changing. Notice it's fairly easy to identify the lines that create the header of the DataWindow in our example. You can see that each line in the exported syntax is in plain English and is merely a list of the attributes you'd normally set in your DataWindow painter, written out longhand. Notice the defined text fields that are identified as "band=header" - these are the ones we'll be concentrating on in our example. You can see that one of them is defined as text="January." This identifies the text portions in the band=header group we're looking for. Fortunately, PowerBuilder groups the data in a straightforward fashion, making it easy to find and identify the data you'll need to use.
Creating the DataWindow from Syntax
What we need to do is use this data to create a string that we can later use to create the DataWindow from syntax. First, let's take out the portions above the lines we want to change and save that text into a command button. You can select the lines above the four lines that define the header (everything from the beginning of the text SRD file to the first band="header" statement) and paste them into the clicked event of a command button. Now we add some code to create a single string from all of those lines of data. Please note that there are other ways of handling these strings, such as retrieving them from a database or even directly from your saved .SRD file. You can choose the method that best suits your programming environment. While pasting into a command button is not the most efficient way of coding, it's the easiest to demonstrate. The reason we create a single string containing all of these lines of the .SRD is that our DataWindow create statement takes a single string as its argument. It's also worth noting that I've added the ~r~n (carriage return linefeed) to each of the lines so that if you choose to display the syntax to a multiline edit, you'll be able to easily identify the components of the DataWindow during your debug process.
Achieving Flexibility
Take a close look at the code snippet in Listing 1. This piece of code is a basic loop from a beginning date to an ending date (using the daysafter function in PowerBuilder) to generate the day portion of the date for each day in the range. The day is parsed into its two components (the first and second characters representing a day such as 24) and the string that will be used as the create is altered based on the results. Notice how the "x=" component of the syntax is assigned a value by the formula: ls_x = String((37 * ll_days) + ((ll_days -1) * 4) + 951) Let's examine the x value. What we're trying to accomplish with this statement is an offset from the first x position in the DataWindow (x=951 is where the leftmost element such as the January header exists) and create a new element starting at this point and continuing to the right. Each element in the header you create will be placed 37 PBUs to the right of the last element created. To simplify, 37 is the width attribute of the day elements as viewed in your DataWindow painter (the 2 or 4 in the 24th of the month). We also add four PBUs to each element after the first to have the elements line up correctly. The four PBUs represent the additional space needed for the box border to line up nicely between the elements. I wanted the screen to look as much like a grid as possible. (If you weren't going to use the box outline attribute, you wouldn't need to add the additional four PBUs per horizontal element.) We then use the ll_days to give us the element number starting with 1 between the start and ending dates. The value of ls_x is just the string representation of where we want the element to appear horizontally on the final screen. Next we examine the "text=" portion of the DataWindow syntax, where we simply add the 10s portion of the date (either " ", "1", "2", "3") for the upper line in the header or the 1s portion of the date (0 through 9) for the lower line. How did we tell the upper line from the lower one? The two "y=" values in the text string can be used to identify the individual displayed objects that make up our displayed date in the DataWindow. We can identify the line containing y=136 as the line that produces the 10s portion of our displayed date (i.e., the 3 in 31st); the line identified by the y=196 statement identifies the 1s portion of our demo line (the 1 in 31st). The 3 prints on the line above the 1 in 31 so the dates take up less displayed real estate. If you weren't sure which was which, you could have looked at your DataWindow painter and examined the x and y properties of the fields. That's the meat of your code here, generating the portion of the DataWindow that would represent dates. The farther apart the dates are, the more lines will be generated. Now go back to the .SRD file you created earlier and add the remaining lines of the DataWindow syntax. Code the button to concatenate these lines to your string and remember to add the ~r~n! You are now ready to create the DataWindow programmatically. Using the create function in PowerBuilder, you can dynamically create the DataWindow in dw_1 (the DataWindow object on the window). The syntax for creating the DataWindow from the syntax is: Dw_1.Create(ls_syntax,ls_error) where (1) ls_syntax will contain the DataWindow create script you created from a mixture of the .SRD file and your own additional logic and (2) ls_error will contain any errors when the DataWindow is created. That's it. Your new DataWindow is ready to use, just as if you had created it in the painter. If you choose to download the source code for this article, I've included an extra window showing an expanded version of the results you can achieve with this technique (see Figure 5). While this approach is very flexible, it should be used only when you can't determine the entire structure of your DataWindow while in design mode. The trade-off here is speed of execution: the DataWindow you create at design time using the painter will outperform the one you create here. However, in this particular situation, and others where it is desirable to maintain a higher level of presentation style than is afforded by the grid, using the create statement provides a manageable alternative. Please download the complete example, which includes the code referenced here, along with a working window that will create the DataWindow described above at runtime. When you compare the .SRD file with the script in the command button, it will become much clearer... how easy the process is.
* * *
Author's Note: This article was inspired in part by Buck Woolley's article "Not Your Father's Datawindow" (PBDJ, Vol. 8, issue 7), which refreshed my memory about how powerful the DataWindow is, and how much we take this for granted as PowerBuilder developers. Reader Feedback: Page 1 of 1
Your Feedback
Enterprise Open Source Magazine Latest Stories . . .
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||