[flexcoders] Re: Overriding text display in DataGridItemRenderer
Thanks very much Tracy, that's exactly what I was missing. For the record, here's the label function: package com.myco.components { import mx.controls.dataGridClasses.DataGridColumn; import mx.formatters.DateFormatter; public class DateRenderer { private var _formatter:DateFormatter public function DateRenderer() { super(); _formatter = new DateFormatter(); _formatter.formatString=EEE, DD MMM at LL:NN A; } private function isoToDate(value:String):Date { var dateStr:String = value; dateStr = dateStr.replace(/-/g, /); dateStr = dateStr.replace(T, ); dateStr = dateStr.replace(Z, GMT-); return new Date(Date.parse(dateStr)); } public function render( data:Object, column:DataGridColumn ) : String { if (! data) { return n.a.; } var dateString:String = data[column.dataField]; if (! dateString) { return n.a.; } var date:Date = isoToDate(String(dateString)); return _formatter.format(date); } } } I create an instance of this in my subclass of DataGrid, and then just set the labelFunction property of date columns to _dateRenderer.render. --- In flexcoders@yahoogroups.com, Tracy Spratt [EMAIL PROTECTED] wrote: If really all you want to do is, override the text, then this is overkill. Just use a labelFunction(). But if you want to do an item renderer, I should think you would set the display in the set data() override. Well, rather in the the commitProperties function, after invalidating properties in set data (). Tracy --- In flexcoders@yahoogroups.com, karlgold karlgold@ wrote: I'm trying to implement a custom item renderer in ActionScript that parses an ISO date string (which is the way the date is always represented in my data feed) and formats it for display in a DataGrid column. I have tried multiple variations on this: package com.mycompany.components { import mx.controls.dataGridClasses.DataGridItemRenderer; import mx.controls.dataGridClasses.DataGridListData; import mx.controls.listClasses.BaseListData; import mx.formatters.DateFormatter; public class DateRenderer extends DataGridItemRenderer{ private var _formatter:DateFormatter public function DateRenderer() { super(); _formatter = new DateFormatter(); _formatter.formatString=EEE, DD MMM at LL:NN A; } private function isoToDate(value:String):Date { var dateStr:String = value; dateStr = dateStr.replace(/-/g, /); dateStr = dateStr.replace(T, ); dateStr = dateStr.replace(Z, GMT-); return new Date(Date.parse(dateStr)); } override public function set listData( row:BaseListData ) : void { super.listData = row; var data:String = row.label; if (data) { var date:Date = isoToDate(data); super.text = _formatter.format(date); } else { super.text = n.a.; } super.invalidateDisplayList(); } } } However, the data grid always displays the raw ISO date rather than the formatted one. I stepped through the code and noticed that DataGridItemRenderer.validateProperties() always sets the text property to _listData.label. I can see my formatted text value getting reset to the raw data value every time. Is there some way around this short of copying and hacking up my own version of DGIR? I also tried extending Label; this displayed the formatted date but all the normal mouse behaviors (highlighting on mouseover, selecting on click) stopped working in that column. Really all I want to do is override the text that DGIR displays. Thanks for any guidance, Karl
[flexcoders] Overriding text display in DataGridItemRenderer
I'm trying to implement a custom item renderer in ActionScript that parses an ISO date string (which is the way the date is always represented in my data feed) and formats it for display in a DataGrid column. I have tried multiple variations on this: package com.mycompany.components { import mx.controls.dataGridClasses.DataGridItemRenderer; import mx.controls.dataGridClasses.DataGridListData; import mx.controls.listClasses.BaseListData; import mx.formatters.DateFormatter; public class DateRenderer extends DataGridItemRenderer{ private var _formatter:DateFormatter public function DateRenderer() { super(); _formatter = new DateFormatter(); _formatter.formatString=EEE, DD MMM at LL:NN A; } private function isoToDate(value:String):Date { var dateStr:String = value; dateStr = dateStr.replace(/-/g, /); dateStr = dateStr.replace(T, ); dateStr = dateStr.replace(Z, GMT-); return new Date(Date.parse(dateStr)); } override public function set listData( row:BaseListData ) : void { super.listData = row; var data:String = row.label; if (data) { var date:Date = isoToDate(data); super.text = _formatter.format(date); } else { super.text = n.a.; } super.invalidateDisplayList(); } } } However, the data grid always displays the raw ISO date rather than the formatted one. I stepped through the code and noticed that DataGridItemRenderer.validateProperties() always sets the text property to _listData.label. I can see my formatted text value getting reset to the raw data value every time. Is there some way around this short of copying and hacking up my own version of DGIR? I also tried extending Label; this displayed the formatted date but all the normal mouse behaviors (highlighting on mouseover, selecting on click) stopped working in that column. Really all I want to do is override the text that DGIR displays. Thanks for any guidance, Karl
[flexcoders] Re: How to measure a Menu before calling show()?
Thanks Doug. Interestingly enough, the public method UIComponent.validateNow() does exactly that (frameworks/source/mx/core/UIComponent.as): public function validateNow():void { UIComponentGlobals.layoutManager.validateClient(this); } But calling that still doesn't seem to set the width and height of the menu. I poked around the framework code a bit more, but before I got anywhere it occurred to me to just do this: var itemMenu:Menu = Menu.createMenu(null, menuData, true); itemMenu.iconField = icon; itemMenu.show(x, y); itemMenu.hide(); var x:Number = e.stageX; var y:Number = e.stageY; var width:Number = itemMenu.getExplicitOrMeasuredWidth(); var height:Number = itemMenu.getExplicitOrMeasuredHeight(); if (x + width this.stage.width) { // show menu to the left of the cursor x -= width; } if (y + height this.stage.height) { // show menu above the cursor y -= height; } itemMenu.show(x, y); That seems to work fine without any noticeable flicker (at least on my 3-year-old laptop). And yes, your scrollable menu looks great and I plan to use it! Regards, Karl --- In flexcoders@yahoogroups.com, Doug McCune [EMAIL PROTECTED] wrote: If you're comfortable looking at the source code for the framework classes, then check out the source of MenuBar.as at line 1574, see the showMenu() method. That has logic that repositions the menu so that it remains on the stage. You could use that code and re-purpose it a little to get it working for your situation. It looks like the key line in there is this: UIComponentGlobals.layoutManager.validateClient(menu, true); which will validate the size of the Menu before you then use the width and height to check the x and y position. Also, see if my Scrollable Menu component might fit your needs: http://dougmccune.com/blog/2007/01/26/even-better-scrollable-menus- for-flex/ -Doug karlgold wrote: I want to display a popup menu when the user clicks in a certain spot in application: private function showContextMenu(e:MouseEvent):void { var menuData:Array = new Array(); // populate menuData var itemMenu:Menu = Menu.createMenu(null, menuData, true); itemMenu.show(e.stageX, e.stageY); } This works fine. However, if the user clicks close to the bottom or right margin of the application, the menu is cut off. I'd like to do something like this: private function showContextMenu(e:MouseEvent):void { var menuData:Array = new Array(); // populate menuData var itemMenu:Menu = Menu.createMenu(null, menuData, true); // how to tell a Menu to measure its width and height before // displaying it? var x:Number = e.stageX; var y:Number = e.stageY; if (x + itemMenu.width this.stage.width) { // show menu to the left of the cursor x -= itemMenu.width; } if (y + itemMenu.height this.stage.height) { // show menu above the cursor y -= itemMenu.height; } itemMenu.show(x, y); } It appears that the width and height are 0 prior to calling show (). Is there any way to measure the menu before drawing it? Thanks, Karl
[flexcoders] How to measure a Menu before calling show()?
I want to display a popup menu when the user clicks in a certain spot in application: private function showContextMenu(e:MouseEvent):void { var menuData:Array = new Array(); // populate menuData var itemMenu:Menu = Menu.createMenu(null, menuData, true); itemMenu.show(e.stageX, e.stageY); } This works fine. However, if the user clicks close to the bottom or right margin of the application, the menu is cut off. I'd like to do something like this: private function showContextMenu(e:MouseEvent):void { var menuData:Array = new Array(); // populate menuData var itemMenu:Menu = Menu.createMenu(null, menuData, true); // how to tell a Menu to measure its width and height before // displaying it? var x:Number = e.stageX; var y:Number = e.stageY; if (x + itemMenu.width this.stage.width) { // show menu to the left of the cursor x -= itemMenu.width; } if (y + itemMenu.height this.stage.height) { // show menu above the cursor y -= itemMenu.height; } itemMenu.show(x, y); } It appears that the width and height are 0 prior to calling show(). Is there any way to measure the menu before drawing it? Thanks, Karl