h4. Introduction This weblog is about a class that produces and destroys docking containers (good old Controls Framework technology) on demand while arranging them on the screen. Although far from being the hot topic, the Controls Framework (CFW) technology is still in use, and for those of you who didnt completely migrate to BSPs or WebDynpros (I suppose there are a few girls and guys out there), this might be a chance to get a fully functional handy little component plus an innovative idea in object-oriented ABAP program design. h4. Docking containers Just short explanation for those who might be less familiar with docking containers: Docking containers are ABAP objects of class CL_GUI_DOCKING_CONTAINER which serve, like other containers, to store controls like ALV grid, trees, other containers etc within. They are specific by their characteristic that they dont need a dynpro screen control to open in, and they dont float freely like dialogbox containers. They rather dock at specified side of a screen. In their constructor, its possible to define their size and docking side (left, right, top or botton). If more containers are created, they dock at each other from outside towards inside of the screen. h4. The standard way The problem here is managing space. When you create the first container, its easy. You want it to occupy the entire screen because theres no reason to save space, and you want user to have the best possible overview. So you can exaggerate with dimensions SAP is clever and the container will fit to screen nicely. I have created a demo to show you this. I put a Dynamic Document control in a container with a close button and a caption with ordinal number and docking side. This is just to see something in the container and to be able to close it. Otherwise it performs no functionality. In real programs, of course, containers will contain something useful. Lets see how it looks if I dock it at top: DATA: o_container TYPE REF TO cl_gui_docking_container. CREATE OBJECT o_container EXPORTING extension = 1500 "exaggerated by far side = o_container->dock_at_top. And Ill get
It looks good. But if I create another one I get
Now you probably think this guy is fooling us its the same picture. But its not. Take a good look theres a little barely visible bar under the container. Its the new container placed below the first one. It docked properly at its bottom, but noone told the first one to resize and make space! Now its users task to realize that this is not an error. The user should reach at the bottom and resize the first container to see the new one, like
The same works for destruction when user chooses to close a control and its container. If done in an usual way, by o_container->free( ) the container would just disappear and leave a hole in the screen. What do you think? Would users like my new application? I would probably end with pizza remaining over my face. Todays remaining, if Im lucky. h4. Containers controller What is the solution then? You can have your application counting containers and redistributing space evenly every time the new one is added, as well as when an obsolete one is removed. This sounds reasonable, but why having each application dealing with this? The algorithm might not be simple (destruction gave me a hard time), and once tuned, theres no need to repeat this over and over. I think that the best would be to create a generic and reusable component to manage containers. I created a component that has 2 public methods: GET_CONTAINER and DESTROY_CONTAINER. Its a class that never instantiates and all its attributes and methods are static. Why is this? This is because only one program can run in one session, and it has only one screen where docking containers can open. Therefore it would make no sense to have more container controller objects in one program. This is why its a class that only has static components. When I want a container, Ill simply do: DATA: o_container TYPE REF TO cl_gui_docking_container. o_container = lcl_cont_controller=>get_container( ). When I want it to disappear Ill do: lcl_cont_controller=>destroy_container( o_container ). I have created a demo program which has a command tree to the left. Note that the command tree is NOT controlled by the container controller, so it will always stay as is (unless resized by user). You can freely combine independent containers with those controlled by this component. The tree has 4 commands, for creating containers docked at left, right top and bottom.
I played with it by clicking the commands by random and observed the result. For example: * TOP * * LEFT * * BOTTOM * * RIGHT * * TOP * * BOTTOM * It resulted with:
![]()
And then I closed them, again in randomly chosen order:
![]()
User can open indefinite number of controllers, but of course, at certain point it stops making sense. But its up to user to decide because technically its not limited. No matter how many opened, they will be distributed evenly, and the same will work in reversal process, when user starts to close them.
Theres a drawback, however (or an advantage - depends on how you look at it). The program has total disrespect for the user. No matter how user resizes containers, they will be distributed evenly at the next container creation or destruction. Feel free to adapt this to your needs. h4. Demo Implementation I use this handy component daily in my applications. You can try it in a demo which is actually one single ABAP. It's an object program, and it's heart is the class LCL_CONT_CONTROLLER which you can easily make a dictionary class and reuse. For your better overview, heres the program's static UML diagram: ![]()
↧