Flex DataGrid Header Column Separator - actionscript-3

I'm using an mx:DataGrid (in a Halo theme) and I'm having some issues with the header column separators/vertical grid line colors. Does anyone know how to customize/change the line color?
Thanks!
--Moe

Datagrid has two styles horizontalSeparatorSkin and verticalSeparatorSkin style which you can override. It seems you need to override the later.
<mx:DataGrid id="grid" verticalGridLines="true" verticalSeparatorSkin="{VerticalSeparatorSkin}">
<mx:columns>
<mx:DataGridColumn dataField="lbl" />
<mx:DataGridColumn dataField="val"/>
</mx:columns>
</mx:DataGrid>
Now you can write this class as:
public class VerticalSeparatorSkin extends ProgrammaticSkin
{
public function VerticalSeparatorSkin()
{
super();
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
// draw a line at the bottom of the rectangle defined by
// unscaledWidth and unscaledHeight
var g:Graphics = this.graphics;
g.clear();
g.lineStyle(3, 0x00FF00); // change thickness / color here
g.moveTo(0,unscaledWidth);
g.lineTo(unscaledWidth, unscaledHeight);
}
}
This should do the work. Another option is to customize the datagrid itself.
public class MyCustomGrid extends DataGrid
{
public function MyCustomGrid()
{
super();
}
override protected function drawVerticalLine(s:Sprite, colIndex:int, color:uint, x:Number):void
{
var contentHolder:ListBaseContentHolder = s.parent.parent as ListBaseContentHolder;
var g:Graphics = s.graphics;
g.lineStyle(3, color); // change the thickness here
g.moveTo(x, 0);
g.lineTo(x, contentHolder.height);
}
}
And this can be used then in place of regular DataGrid.

Related

DataGrid ItemRenderer

Here's the thing: I've this DataGrid that holds a column with the purpose of handle some actions. So, this DataGrid have several data columns and, at the end there is this special column.
At this special column named "operations" there are two icons; one of 'em shows an alarm icon (like a little bell). So, what I've to accomplish is that, initially the alarm icon shows invisible; when the user sets an alarm (through another interface) the alarm icon shows up (with default style color) and when it's time to fire the alarm the alarm icon is supposed to take another style color (like yellow).
So, I've this next definition:
<mx:DataGrid id="dgSomeValues"
dragEnabled="true"
draggableColumns="false"
width="100%" height="100%"
horizontalScrollPolicy="off"
resizableColumns="true"
rowHeight="19">
<components:columns>
<mx:DataGridColumn id="dgcItem" headerText="{resourceManager.getString('resources','columnItem')}" width="70" resizable="false"/>
<!--
Some other dataGridColumns
-->
<mx:DataGridColumn id="dgcOperation" headerText=" " width="50" resizable="false">
<mx:itemRenderer>
<fx:Component>
<components:OperationItemRenderer/>
</fx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</components:columns>
And definition for OperationItemRenderer is like this:
import flash.events.MouseEvent;
import com.broker.control.BrokerEvent;
import mx.containers.HBox;
public class OperationItemRenderer extends HBox
{
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* Alarm Button --> bell
**/
private var btnAlarm:Icon;
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor
**/
public function OperationItemRenderer()
{
super();
this.setStyle("horizontalGap",0);
}
//--------------------------------------------------------------------------
//
// Overridden methods
//
//--------------------------------------------------------------------------
/**
* #inheritDoc
**/
override public function set data(value:Object):void
{
super.data = value;
}
/**
* #inheritDoc
**/
protected override function createChildren():void
{
super.createChildren();
if (!btnAlarm){
btnAlarm = new Icon();
btnAlarm.styleName = ""; // Initially do not shows any icon.
btnAlarm.enabled = true;
btnAlarm.addEventListener(MouseEvent.CLICK, btnAlarmClickHandler,false,0,true);
addChild(btnAlarma);
}
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (btnAlarm){
btnAlarm.width = unscaledWidth/2;
btnAlarm.height= unscaledHeight;
}
}
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* If this item has an alarm, then it will show an icon.
* States for alarm icon are: Default --> icnAlarmOff
* Fired --> icnAlarm
*/
public function upgradeIcon(toogle:Boolean):void
{
btnAlarm.styleName = toogle ? "icnAlarm" : "icnAlarmOff";
}
//--------------------------------------------------------------------------
//
// Event Handlers
//
//--------------------------------------------------------------------------
protected function btnAlarmaClickHandler(event:MouseEvent):void
{
if (btnAlarm.styleName == "favIcnAlarma") {
var evt:BrokerEvent;
evt = new BrokerEvent(BrokerEvent.SETUP_ALARM);
dispatchEvent(evt);
}
}
}
The function "upgradeIcon" it's supposed to be called from another section in the application where a rowFunction it's called everytime the DataGrid's datasource is refreshed. At this rowFunction I want to find a way to access DataGrid ItemRenderer so that way I'll be able to call this upgradeIcon function.
The question is, how can I access DataGrid's ItemRenderer programatically? What I already tried is something like this:
var c:ClassFactory = view.dgcOperation.itemRenderer as ClassFactory;
if (c != null && c.generator != null) { // c never is null at this point
var f:OperationItemRenderer = c.generator as OperationItemRenderer;
f.upgradeIcon(change); // f it's always null
//(c.generator as OperationItemRenderer).upgradeIcon(change);
}
But this approach does not work. Any help would be greatfully appreciated.
Thanks in advance!
try to dispatch an event when user set alarm...and add a listener of this event in your renderer, so when a new alarm is set, an event will be dispatched from your alarm interface, and be captured in your renderer which will update your icon style.
Your datagrid must be having a data provider of value objects (say Report is name of your class) . If you have marked your Report class bindable then any change in any of its property will dispatch PropertyChangeEvent and then you can override set Data method in the item-renderer and based on the value of that property you should have taken necessary action.
ItemRenderers are recycled and fetching them in this was is a bad practice. You should not alter an ItemRenderer directly rather alter the underlying object.

overiding flex candlestick chart itemrenderer

I am trying to override a candlestick chart item renderer but cannot issue base class rendering on top of my own
from the flex api help:
itemRenderer
Type: mx.core.IFactory CSS Inheritance: No
Language Version: ActionScript 3.0 Product Version: Flex 3 Runtime Versions: Flash9, AIR 1.1
A factory that represents the class the series will use to represent individual items on the chart. This class is instantiated once for each element in the chart. Classes used as an itemRenderer should implement the IFlexDisplayObject, ISimpleStyleClient, and IDataRenderer interfaces. The data property is assigned the chartItem that the skin instance renders.
as file declaration for custom renderer:
package { // Empty package.
import mx.charts.series.items.HLOCSeriesItem;
import mx.core.IDataRenderer;
import mx.core.IFlexDisplayObject;
import mx.styles.ISimpleStyleClient;
import flash.display.Graphics;
import mx.charts.chartClasses.HLOCSeriesBase;
import mx.charts.series.CandlestickSeries;
public class CycleColorRenderer extends HLOCSeriesBase
implements IFlexDisplayObject, ISimpleStyleClient, IDataRenderer {
private var colors:Array = [0xCCCC99,0x999933,0x999966];
private var _chartItem:HLOCSeriesItem;
public function CycleColorRenderer() {
super();
}
public function get data():Object {
return _chartItem;
}
public function set data(value:Object):void {
_chartItem = value as HLOCSeriesItem;
invalidateDisplayList();
}
override protected function
updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
/* var g:Graphics = graphics;
g.clear();
g.beginFill(colors[(_chartItem == null)? 0:0]);
g.drawRect(0, 0, unscaledWidth, unscaledHeight);
g.endFill();
*/
/*
if( _chartItem && _chartItem.index == 0) {
g.beginFill(0xFF0000); // Red line, you can select your own color
// Draw the line across the chart. This is actually a rectangle with height 1.
g.drawRect(-50,0,this.parent.width+50, 1);
g.endFill();
}
*/
}
} // Close class.
} // Close package.
mxml declaration:
<mx:CandlestickSeries
dataProvider="{TICKER}"
openField="open"
highField="high"
lowField="low"
closeField="close"
displayName="TICKER"
itemRenderer="CycleColorRenderer"
>
The chart is being rendered, but instead of default candle sticks theres void in the place of them, but I can retrieve bars properties and render myself - I would just like to issue base renderer from the base class and just draw on top of it. What am I missing?

AdvancedDataGridColumnGroup cell color

How to specify the color of the text inside a particular cell contained in AdvancedDataGridColumnGroup in Flex? The code is in action script and the text color varies according to the value that the cell contains. i.e. if it is negative value it has to be displayed in red otherwise black.
Please mention if there is any work around too!
Thanks!
I've done example with functionality that you describe. Hope, it will help.
<mx:AdvancedDataGrid id="grid"
itemRenderer="MyAdvancedDataGridItemRenderer"
dataProvider="{dataProvider}"
width="200" height="100%">
<mx:groupedColumns>
<mx:AdvancedDataGridColumn dataField="name"/>
<mx:AdvancedDataGridColumn dataField="score"/>
</mx:groupedColumns>
</mx:AdvancedDataGrid>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var dataProvider:ArrayCollection = new ArrayCollection([
{name:"Name1", score:-12},
{name:"Name2", score:10},
{name:"Name3", score:-100},
]);
]]>
</mx:Script>
</mx:Application>
And class MyAdvancedDataGridItemRenderer.as:
package
{
import mx.controls.advancedDataGridClasses.AdvancedDataGridItemRenderer;
import mx.controls.advancedDataGridClasses.AdvancedDataGridListData;
public class MyAdvancedDataGridItemRenderer extends AdvancedDataGridItemRenderer
{
public function MyAdvancedDataGridItemRenderer()
{
super();
}
override public function validateProperties():void
{
super.validateProperties();
if (listData)
{
var item:Object = AdvancedDataGridListData(listData).item;
if (AdvancedDataGridListData(listData).dataField == "score") {
setStyle("color", item.score < 0 ? 0xff0000 : 0x000000);
}
}
}
}
}

How to increase horizontalgridline thickness in Flex 3

i have set horizontal gridlines between rows of a datagrid to true. But i'm unable to increase its thickness. how to do it?
There are two ways you can go about solving this. If you check the docs, DataGrid has a horizontalSeparatorSkin style. The docs state that this is undefined by default, and in which case the grid uses it's drawHorizontalLine() method to draw the lines.
So you can either set the horizontalSeparatorSkin style to your own class that extends ProgramaticSkin or extend the DataGrid class and override the drawHorizontalLine() method. Both are fairly easy to do, here's app with an example of each one:
App
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*"
layout="vertical"
creationComplete="onCreationComplete()">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
protected function onCreationComplete():void
{
var dp:ArrayCollection= new ArrayCollection([ { label: "one", value: 1 }, { label: "two", value: 2 }, { label: "three", value: 3 } ]);
grid.dataProvider=dp;
customGrid.dataProvider=dp;
}
]]>
</mx:Script>
<mx:DataGrid id="grid" horizontalGridLines="true" horizontalSeparatorSkin="{HorizontalSeparatorSkin}">
<mx:columns>
<mx:DataGridColumn dataField="label" />
<mx:DataGridColumn dataField="value"/>
</mx:columns>
</mx:DataGrid>
<local:CustomGrid id="customGrid" horizontalGridLines="true" horizontalGridLineColor="#FF0000">
<local:columns>
<mx:DataGridColumn dataField="label" />
<mx:DataGridColumn dataField="value"/>
</local:columns>
</local:CustomGrid>
</mx:Application>
Programatic skin (HorizontalSeparatorSkin.as):
package
{
import flash.display.Graphics;
import mx.skins.ProgrammaticSkin;
public class HorizontalSeparatorSkin extends ProgrammaticSkin
{
public function HorizontalSeparatorSkin()
{
super();
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
// draw a line at the bottom of the rectangle defined by
// unscaledWidth and unscaledHeight
var g:Graphics = this.graphics;
g.clear();
g.lineStyle(3, 0x00FF00); // change thickness / color here
g.moveTo(0,unscaledHeight);
g.lineTo(unscaledWidth, unscaledHeight);
}
}
}
Custom grid (CustomGrid.as):
package
{
import flash.display.Graphics;
import flash.display.Sprite;
import mx.controls.DataGrid;
import mx.controls.listClasses.ListBaseContentHolder;
public class CustomGrid extends DataGrid
{
public function CustomGrid()
{
super();
}
override protected function drawHorizontalLine(s:Sprite, rowIndex:int, color:uint, y:Number):void
{
var contentHolder:ListBaseContentHolder = s.parent.parent as ListBaseContentHolder;
var g:Graphics = s.graphics;
g.lineStyle(3, color); // change the thickness here
g.moveTo(0, y);
g.lineTo(contentHolder.width, y);
}
}
}

How to make simple actionscript itemrenderer for Flex Mobile?

I've been making mxml itemRenderers, but from what I hear at adobe, for the Flex Mobile projects they keep saying "make your item renderers with only actionscript3, no mxml"
So...I have this list where im trying to remake the itemRenderer in actionscript the best way I can guess to do so. can some one let me know if im doing something wrong? Maybe I should be doing it in a whole different file..i dont know this is my first time making an all actionscript3 IR.
The text appears, but now my scollToBottom() function no longer works now. I used it with my mxml itemrenderer and it worked fine. so i thought maybe I was doing something wrong here...So this is my primary problem, im assuming something is wrong with how im doing the itemrenderer and thats why the scroll to bottom function wont work anymore.
//my scroll to bottom function that i run after i put something in the list. since its a chat, this way it auto scrolls down for the user to read the latest message.
protected function scrollToBottom():void {
// update the verticalScrollPosition to the end of the List
// virtual layout may require us to validate a few times
var delta:Number = 0;
var count:int = 0;
while (count++ < 10){
chat_list.validateNow();
delta = chat_list.layout.getVerticalScrollPositionDelta(NavigationUnit.END);
chat_list.layout.verticalScrollPosition += delta;
if (delta == 0)
break;
}
}
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" width="100%" height="100%" autoDrawBackground="false" contentBackgroundAlpha=".3" creationComplete="itemrenderer1_creationCompleteHandler(event)">
<fx:Style>
#namespace s "library://ns.adobe.com/flex/spark";
#font-face {
src: url("assets/fonts/mpb.ttf");
fontFamily: "myFont";
embedAsCFF: true;
advancedAntiAliasing: true;
}
</fx:Style>
<fx:Script>
<![CDATA[
import mx.core.FlexGlobals;
import mx.core.UIComponent;
import mx.events.FlexEvent;
import spark.components.Label;
import spark.components.VGroup;
private var msgTxt:Label = new Label();
private var nameLabel:Label = new Label();
private var mainContainer:VGroup = new VGroup();
protected function itemrenderer1_creationCompleteHandler(event:FlexEvent):void
{
maxWidth=this.width;
mainContainer.paddingBottom=10;
mainContainer.paddingTop=10;
mainContainer.verticalAlign="bottom";
mainContainer.explicitWidth=this.width;
this.addElement(mainContainer);
msgTxt.setStyle("fontFamily","myFont");
msgTxt.setStyle("color","#000000");
msgTxt.setStyle("fontSize","35");
msgTxt.setStyle("paddingRight","15");
msgTxt.setStyle("paddingTop","10");
msgTxt.setStyle("paddingLeft","15");
msgTxt.explicitWidth=this.width;
mainContainer.addElement(msgTxt);
nameLabel.setStyle("fontFamily","myFont");
nameLabel.setStyle("color","#666666");
nameLabel.setStyle("paddingLeft","5");
nameLabel.setStyle("fontSize","24");
nameLabel.explicitWidth=this.width;
mainContainer.addElement(nameLabel);
}
override public function set data(value:Object):void {
super.data = value;
if (data == null)
return;
if(data.systemMsg)
{
}
if(data.name)
{
nameLabel.text=data.name;
if(data.name == "You: ")
{
nameLabel.setStyle("textAlign","right");
msgTxt.setStyle("textAlign","right");
nameLabel.setStyle("paddingRight","5");
}
else if(data.name == "Them: ")
{
nameLabel.setStyle("textAlign","left");
msgTxt.setStyle("textAlign","left");
}
else
{
nameLabel.setStyle("textAlign","left");
msgTxt.setStyle("textAlign","left");
}
}
if(data.icon)
{
}
if(data.msg)
{
msgTxt.text=data.msg;
}
}
]]>
</fx:Script>
</s:ItemRenderer>
what you are missing are a few function calls that need to be overwritten so that the size and position of your items are correctly measured at the right point in the work flow. Here is a copy/paste of the code from the default Flex Template.
Also, from the look of things is looks like you are trying to put as3 code into a Flex ItemRenderer, but that isn't going to help you performance wise. You are going to need a pure AS3 class that extends a Class such as LabelItemRenderer
/**
* #private
*
* Override this setter to respond to data changes
*/
override public function set data(value:Object):void
{
super.data = value;
// the data has changed. push these changes down in to the
// subcomponents here
}
/**
* #private
*
* Override this method to create children for your item renderer
*/
override protected function createChildren():void
{
super.createChildren();
// create any additional children for your item renderer here
}
/**
* #private
*
* Override this method to change how the item renderer
* sizes itself. For performance reasons, do not call
* super.measure() unless you need to.
*/
override protected function measure():void
{
super.measure();
// measure all the subcomponents here and set measuredWidth, measuredHeight,
// measuredMinWidth, and measuredMinHeight
}
/**
* #private
*
* Override this method to change how the background is drawn for
* item renderer. For performance reasons, do not call
* super.drawBackground() if you do not need to.
*/
override protected function drawBackground(unscaledWidth:Number,
unscaledHeight:Number):void
{
super.drawBackground(unscaledWidth, unscaledHeight);
// do any drawing for the background of the item renderer here
}
/**
* #private
*
* Override this method to change how the background is drawn for this
* item renderer. For performance reasons, do not call
* super.layoutContents() if you do not need to.
*/
override protected function layoutContents(unscaledWidth:Number,
unscaledHeight:Number):void
{
super.layoutContents(unscaledWidth, unscaledHeight);
// layout all the subcomponents here
}