Archive for Monkey Patching
Preventing User Dragging Panel Off Screen
Posted by: | CommentsMy most recent monkey patch to the Flex framework code took place in the Panel class. It is possible to drag a Panel completely off the screen, such that the user has no way of dragging it back should they release the mouse button.
Panel has a private handler private function systemManager_mouseMoveHandler (event:MouseEvent) : void that gets called before any mouse event handlers you might listen for should you extend Panel or try any other object oriented approach. There are also two private variables on the Panel class, regX and regY which store the location the mouse was pressed on the Panel’s title bar, and are set in the startDragging() method. (These numbers are useful for determining if the Panel is being dragged off screen as well as for determining where the top-left corner of the Panel is).
I decided to keep it simple and only prevent the user from dragging the Panel off the left or upper edges of the browser. (You can do the same for the bottom and right edges by performing similar calculations… but I didn’t.)
Here’s the code that does the checking (inside systemManager_mouseMoveHandler():
var sx : int = event.stageX; var sy : int = event.stageY; var nx : int = event.stageX - regX; var ny : int = event.stageY - regY; if (nx < 0 && ny < 0) move(0,0); else if (nx < 0 && ny >= 0) move(0, sy-regY); else if (nx >= 0 && ny < 0) move(sx-regX, 0); else move(event.stageX - regX, event.stageY - regY);
Essentially the code detects if the top or left edge of the Panel is in the negative, and if so resets it to zero. There is a stopDragging() method that I originally tried to use in my code, but gave up, because I wanted the user to be able to continue dragging their mouse back onto the browser after they dragged it off.
Adding in the right and bottom will add several more permutations, so I’ve been thinking of more creative ways to handle this, but haven’t got it working the way I want yet. I’ll update this post when I do.
Private Variables and Monkey Patching
Posted by: | CommentsI’ve been pretty busy the past two months finishing up a project for my client. I may have mentioned it before, but their creative vision is pretty intense (especially considering this is an in-house app… in my limited experience I’ve never seen so many resources allocated toward getting the look and feel of an in-house app to be just right).
Anyway, I’ve had to monkey patch approximately 10 Flex framework classes (for various reasons) in order to realize their vision. In each of these cases I’ve first tried to use inheritance or composition to achieve the desired functionality, mostly in terms of interaction. And in each of these cases I was unable to do so, and had to resort to making changes directly in a framework class which I maintain in an mx.controls.etc, etc structure with the rest of my project. I don’t think I need to point out the many evils that this exposes the project to, suffice it to say it’s not ideal.
I just wanted to make an observation as to why I was unable to use normal OOP techniques to achieve the desired functionality. The most common reason I have been unable to extend classes to do what I need is because there are too many private variables being used in protected functions. So if I need to tweak one line of a protected method, I can override it. However, assuming I don’t want to call super.methodName(), there’s no way to recreate the lines that interact with the private variables.
This leaves me two alternatives: 1) monkey patch the file to make the variable protected, or 2) monkey patch the file and just make the change directly to the method. I make that decision depending on whether I’m fixing a bug, or just adding functionality. Either way, it’s still a pain in the butt; and will probably be a bigger pain down the road.
Flex Menu Monkey Patch: Allowing a Branch to be Selected
Posted by: | CommentsSo the interaction designers decided that the branches of a menu needed to be selectable (picture a warped checkbox tree, only it’s a menu… and there aren’t any checkboxes). The default behavior of a Menu in Flex can be described as follows:
1. If you click on a leaf, the leaf is selected.
2. If you click on a branch, the sub menu opens up.
3. If you hover over a branch, the sub menu opens up.
I needed to change #2 to select the branch.
The first thing that I did was sublcass Menu (we’ll call it NewMenu), and overrode (with copies) two obvious methods on the Menu class:
override protected function mouseUpHandler(event : MouseEvent) : void override protected function mouseDownHandler(event : MouseEvent) : void
In those two methods you’ll need to remove any expressions containing something similar to the following:
_dataDescriptor.isBranch(item)
This will allow the branches of your sub class to be treated as leaves. The problem is that Menu class contains this line:
private var subMenu:Menu;
which forces all sub menus to be of type Menu– the only NewMenu will be at the very top! We need all sub menus to be NewMenus. So this is where the monkey patching comes in. You have to change subMenu to a protected variable. Then in your NewMenu class, you can override the function:
mx_internal override function openSubMenu(row : IListItemRenderer) : void
And change the line:
menu = new Menu();
to
menu = new NewMenu();
And you’re done! The reason you need subMenu to be protected is because later on in the method you assign menu to subMenu, and you couldn’t do that from a subclass when it was private. Voila. Interaction designers satisfied.

