在FLEX中创建可交互的TOOLTIP.
FLEX中的TOOLTIP都是静态的,如果想创建一个TOOLTIP上面有按钮,有超级连接,怎么做呢?
示例:
代码:
MXML文件:
MenuToolTipRenderer.as文件:
示例:
代码:
MXML文件:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" initialize="init()"
viewSourceURL="srcview/index.html" width="600" height="300">
<mx:DataGrid id="dg" dataProvider="{tmpArray}" width="550"
mouseOut="dgMouseOut(event)" mouseOver="dgMouseOver(event)" mouseMove="dgMouseMove(event)">
<mx:columns>
<mx:Array>
<mx:DataGridColumn headerText="Label" dataField="label" showDataTips="true" />
<mx:DataGridColumn headerText="Data" dataField="data" />
</mx:Array>
</mx:columns>
</mx:DataGrid>
<mx:Style>
.menuToolTip {
backgroundAlpha: 1;
backgroundColor: #ffffcc;
useRollOver: false;
borderStyle: solid;
borderThickness: 0;
borderColor: #000000;
selectionColor: #7fcdfe;
dropShadowEnabled: true;
cornerRadius: 5;
paddingLeft: 3; paddingRight: 3; paddingTop: 3; paddingBottom: 3;
}
</mx:Style>
<mx:Script>
<![CDATA[
import mx.automation.delegates.controls.ListBaseContentHolderAutomationImpl;
import mx.controls.listClasses.ListBase;
import renderers.MenuToolTipRenderer;
import mx.controls.dataGridClasses.DataGridItemRenderer;
import mx.managers.ToolTipManager;
import mx.controls.Menu;
import mx.events.MenuEvent;
import flash.geom.Point;
[Bindable] private var dgMouseX:Number = 0;
[Bindable] private var dgMouseY:Number = 0;
private var toolTipMenu:Menu;
private var toolTipTimer:Timer;
[Bindable]
public var tmpArray:Array = [{label: '<b>mary</b> had a little lamb', data: 55, link:'http://www.meutzner.com/blog'},
{label: 'All the kings men, and all the kings horses', data: 56, link:'http://www.meutzner.com/blog'},
{label: 'baa baa black sheep, have you any wool', data: 57, link:'http://www.meutzner.com/blog'},
{label: 'jack and jill went up the hill', data: 58, link:'http://www.meutzner.com/blog'},
{label: 'little miss muffet, sat on a tuffet, eating her curds and whey', data: 59, link:'http://www.meutzner.com/blog'}
];
//-------------------------------------------------------------------------
public function init():void
{
ToolTipManager.enabled = false;
}
//-------------------------------------------------------------------------
private function createMenu(data:Object):void
{
toolTipTimer.stop();
var menuData:Array = [{label: data.label, link: data.link}];
toolTipMenu = Menu.createMenu(this, menuData, false);
toolTipMenu.labelField="label";
toolTipMenu.width = 250;
toolTipMenu.setStyle("fontSize", 10);
toolTipMenu.setStyle("themeColor", 0xFF9900);
toolTipMenu.itemRenderer = new ClassFactory(renderers.MenuToolTipRenderer);
toolTipMenu.data = data;
toolTipMenu.selectable = false;
toolTipMenu.setStyle("styleName", "menuToolTip");
toolTipMenu.setStyle("openDuration", 0);
//toolTipMenu.setStyle("selectionEasingFunction", myEasingFunction);
toolTipMenu.addEventListener(MouseEvent.ROLL_OUT, hideToolTip);
toolTipMenu.addEventListener("buttonClicked", catchButtonClick);
var pt1:Point = new Point(this.dgMouseX, this.dgMouseY);
pt1 = dg.localToGlobal(pt1);
//offset this for now to fix slight bug where immediate mouseover of tooltip causes it to hide
toolTipMenu.show(pt1.x+10, pt1.y+0);
}
//-------------------------------------------------------------------------
private function hideToolTip(event:MouseEvent):void
{
//trace("MENU --- " + event.relatedObject + " - " + event.target + " - " + event.currentTarget);
toolTipMenu.hide();
}
//-------------------------------------------------------------------------
private function dgMouseMove(event:MouseEvent):void
{
this.dgMouseX = dg.mouseX;
this.dgMouseY = dg.mouseY;
}
//-------------------------------------------------------------------------
private function dgMouseOver(event:MouseEvent):void
{
this.dgMouseX = dg.mouseX;
this.dgMouseY = dg.mouseY;
//trace("DATAGRID OVER --- " + event.target + " - " + event.currentTarget + " - " + event.relatedObject);
if(event.target is DataGridItemRenderer)
{
if(toolTipMenu != null)
{
if(toolTipMenu.visible && toolTipMenu.data == event.target.data)
return;
}
if(!DataGridItemRenderer(event.target).styleName.showDataTips)
return;
toolTipTimer = new Timer(1000, 0);
toolTipTimer.addEventListener(TimerEvent.TIMER, function():void
{
createMenu(event.target.data);
}
);
toolTipTimer.start();
}
}
//-------------------------------------------------------------------------
private function dgMouseOut(event:MouseEvent):void
{
if(toolTipTimer) toolTipTimer.stop();
//trace("DATAGRID OUT --- " + event.target + " - " + event.currentTarget + " - " + event.relatedObject);
if(event.relatedObject is mx.controls.listClasses.ListBaseContentHolder || event.relatedObject is MenuToolTipRenderer)
{
return;
}
if(event.target is DataGridItemRenderer)
{
if(event.relatedObject is Menu || !event.relatedObject is MenuToolTipRenderer) return;
if(toolTipMenu != null) toolTipMenu.hide();
}
}
//-------------------------------------------------------------------------
private function catchButtonClick(e:Event):void
{
mx.controls.Alert.show(e.target.data.label + " was clicked to take you to " + e.target.data.link);
}
]]>
</mx:Script>
</mx:Application>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" initialize="init()"
viewSourceURL="srcview/index.html" width="600" height="300">
<mx:DataGrid id="dg" dataProvider="{tmpArray}" width="550"
mouseOut="dgMouseOut(event)" mouseOver="dgMouseOver(event)" mouseMove="dgMouseMove(event)">
<mx:columns>
<mx:Array>
<mx:DataGridColumn headerText="Label" dataField="label" showDataTips="true" />
<mx:DataGridColumn headerText="Data" dataField="data" />
</mx:Array>
</mx:columns>
</mx:DataGrid>
<mx:Style>
.menuToolTip {
backgroundAlpha: 1;
backgroundColor: #ffffcc;
useRollOver: false;
borderStyle: solid;
borderThickness: 0;
borderColor: #000000;
selectionColor: #7fcdfe;
dropShadowEnabled: true;
cornerRadius: 5;
paddingLeft: 3; paddingRight: 3; paddingTop: 3; paddingBottom: 3;
}
</mx:Style>
<mx:Script>
<![CDATA[
import mx.automation.delegates.controls.ListBaseContentHolderAutomationImpl;
import mx.controls.listClasses.ListBase;
import renderers.MenuToolTipRenderer;
import mx.controls.dataGridClasses.DataGridItemRenderer;
import mx.managers.ToolTipManager;
import mx.controls.Menu;
import mx.events.MenuEvent;
import flash.geom.Point;
[Bindable] private var dgMouseX:Number = 0;
[Bindable] private var dgMouseY:Number = 0;
private var toolTipMenu:Menu;
private var toolTipTimer:Timer;
[Bindable]
public var tmpArray:Array = [{label: '<b>mary</b> had a little lamb', data: 55, link:'http://www.meutzner.com/blog'},
{label: 'All the kings men, and all the kings horses', data: 56, link:'http://www.meutzner.com/blog'},
{label: 'baa baa black sheep, have you any wool', data: 57, link:'http://www.meutzner.com/blog'},
{label: 'jack and jill went up the hill', data: 58, link:'http://www.meutzner.com/blog'},
{label: 'little miss muffet, sat on a tuffet, eating her curds and whey', data: 59, link:'http://www.meutzner.com/blog'}
];
//-------------------------------------------------------------------------
public function init():void
{
ToolTipManager.enabled = false;
}
//-------------------------------------------------------------------------
private function createMenu(data:Object):void
{
toolTipTimer.stop();
var menuData:Array = [{label: data.label, link: data.link}];
toolTipMenu = Menu.createMenu(this, menuData, false);
toolTipMenu.labelField="label";
toolTipMenu.width = 250;
toolTipMenu.setStyle("fontSize", 10);
toolTipMenu.setStyle("themeColor", 0xFF9900);
toolTipMenu.itemRenderer = new ClassFactory(renderers.MenuToolTipRenderer);
toolTipMenu.data = data;
toolTipMenu.selectable = false;
toolTipMenu.setStyle("styleName", "menuToolTip");
toolTipMenu.setStyle("openDuration", 0);
//toolTipMenu.setStyle("selectionEasingFunction", myEasingFunction);
toolTipMenu.addEventListener(MouseEvent.ROLL_OUT, hideToolTip);
toolTipMenu.addEventListener("buttonClicked", catchButtonClick);
var pt1:Point = new Point(this.dgMouseX, this.dgMouseY);
pt1 = dg.localToGlobal(pt1);
//offset this for now to fix slight bug where immediate mouseover of tooltip causes it to hide
toolTipMenu.show(pt1.x+10, pt1.y+0);
}
//-------------------------------------------------------------------------
private function hideToolTip(event:MouseEvent):void
{
//trace("MENU --- " + event.relatedObject + " - " + event.target + " - " + event.currentTarget);
toolTipMenu.hide();
}
//-------------------------------------------------------------------------
private function dgMouseMove(event:MouseEvent):void
{
this.dgMouseX = dg.mouseX;
this.dgMouseY = dg.mouseY;
}
//-------------------------------------------------------------------------
private function dgMouseOver(event:MouseEvent):void
{
this.dgMouseX = dg.mouseX;
this.dgMouseY = dg.mouseY;
//trace("DATAGRID OVER --- " + event.target + " - " + event.currentTarget + " - " + event.relatedObject);
if(event.target is DataGridItemRenderer)
{
if(toolTipMenu != null)
{
if(toolTipMenu.visible && toolTipMenu.data == event.target.data)
return;
}
if(!DataGridItemRenderer(event.target).styleName.showDataTips)
return;
toolTipTimer = new Timer(1000, 0);
toolTipTimer.addEventListener(TimerEvent.TIMER, function():void
{
createMenu(event.target.data);
}
);
toolTipTimer.start();
}
}
//-------------------------------------------------------------------------
private function dgMouseOut(event:MouseEvent):void
{
if(toolTipTimer) toolTipTimer.stop();
//trace("DATAGRID OUT --- " + event.target + " - " + event.currentTarget + " - " + event.relatedObject);
if(event.relatedObject is mx.controls.listClasses.ListBaseContentHolder || event.relatedObject is MenuToolTipRenderer)
{
return;
}
if(event.target is DataGridItemRenderer)
{
if(event.relatedObject is Menu || !event.relatedObject is MenuToolTipRenderer) return;
if(toolTipMenu != null) toolTipMenu.hide();
}
}
//-------------------------------------------------------------------------
private function catchButtonClick(e:Event):void
{
mx.controls.Alert.show(e.target.data.label + " was clicked to take you to " + e.target.data.link);
}
]]>
</mx:Script>
</mx:Application>
MenuToolTipRenderer.as文件:
package renderers
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextFieldAutoSize;
import mx.controls.Alert;
import mx.controls.LinkButton;
import mx.controls.Menu;
import mx.controls.listClasses.IListItemRenderer;
import mx.controls.menuClasses.IMenuItemRenderer;
import mx.core.EdgeMetrics;
import mx.core.IDataRenderer;
import mx.core.UIComponent;
import mx.core.UITextField;
import mx.events.FlexEvent;
public class MenuToolTipRenderer extends UIComponent implements IMenuItemRenderer, IDataRenderer, IListItemRenderer
{
private var textField:UITextField;
private var clickText:LinkButton;
//-------------------------------------------------------------------------
public function MenuToolTipRenderer()
{
super();
this.addEventListener(FlexEvent.DATA_CHANGE, renderComponent);
this.setStyle("cornerRadius", 5);
this.maxWidth = 250;
}
//-------------------------------------------------------------------------
// Internal variable for the property value.
private var _menu:Menu;
public function get menu():Menu
{
return _menu;
}
public function set menu(value:Menu):void
{
_menu = value;
}
//-------------------------------------------------------------------------
private var _data:Object;
[Bindable("dataChange")]
public function get data():Object {
return _data;
}
public function set data(value:Object):void {
_data = value;
dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
}
//-------------------------------------------------------------------------
private function get borderMetrics():EdgeMetrics
{
return EdgeMetrics.EMPTY;
}
//-------------------------------------------------------------------------
private function renderComponent(event:FlexEvent):void
{
if(_data != null && _data != "null")
{
textField.htmlText = data.label;
invalidateProperties();
invalidateSize();
invalidateDisplayList();
}
}
//-------------------------------------------------------------------------
private function buttonClick(event:Event):void
{
mx.controls.Alert.show("button click");
}
//-------------------------------------------------------------------------
override protected function createChildren():void
{
super.createChildren();
// Create the TextField that displays the tooltip text.
if (!textField)
{
textField = new UITextField();
textField.autoSize = TextFieldAutoSize.LEFT;
textField.mouseEnabled = false;
textField.multiline = true;
textField.selectable = false;
textField.wordWrap = true;
textField.styleName = this;
addChild(textField);
}
}
//-------------------------------------------------------------------------
override protected function measure():void
{
super.measure();
var bm:EdgeMetrics = borderMetrics;
var leftInset:Number = bm.left + getStyle("paddingLeft");
var topInset:Number = bm.top + getStyle("paddingTop");
var rightInset:Number = bm.right + getStyle("paddingRight");
var bottomInset:Number = bm.bottom + getStyle("paddingBottom");
var widthSlop:Number = leftInset + rightInset;
var heightSlop:Number = topInset + bottomInset;
textField.wordWrap = false;
if (textField.textWidth + widthSlop > this.maxWidth)
{
textField.width = this.maxWidth - widthSlop;
textField.wordWrap = true;
}
measuredWidth = textField.width + widthSlop;
measuredHeight = textField.height + heightSlop;
this.parent.parent.height = this.parent.height = this.height = measuredHeight + 25;
this.parent.parent.width = this.parent.width = this.width = measuredWidth;
createAdditionalContent(measuredWidth, measuredHeight);
}
private function createAdditionalContent(measuredWidth:Number, measuredHeight:Number):void
{
clickText = new LinkButton();
clickText.label = "More Info";
clickText.width = 70;
clickText.height = 18;
clickText.setStyle("fontSize", 9);
clickText.setStyle("color", "blue");
clickText.buttonMode = true;
clickText.visible = true;
clickText.y = measuredHeight;
clickText.x = measuredWidth - clickText.width - 8;
clickText.addEventListener(MouseEvent.CLICK, dispatchClick);
addChild(clickText);
}
private function dispatchClick(e:Event):void
{
this.dispatchEvent(new Event("buttonClicked", true))
}
}
}
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextFieldAutoSize;
import mx.controls.Alert;
import mx.controls.LinkButton;
import mx.controls.Menu;
import mx.controls.listClasses.IListItemRenderer;
import mx.controls.menuClasses.IMenuItemRenderer;
import mx.core.EdgeMetrics;
import mx.core.IDataRenderer;
import mx.core.UIComponent;
import mx.core.UITextField;
import mx.events.FlexEvent;
public class MenuToolTipRenderer extends UIComponent implements IMenuItemRenderer, IDataRenderer, IListItemRenderer
{
private var textField:UITextField;
private var clickText:LinkButton;
//-------------------------------------------------------------------------
public function MenuToolTipRenderer()
{
super();
this.addEventListener(FlexEvent.DATA_CHANGE, renderComponent);
this.setStyle("cornerRadius", 5);
this.maxWidth = 250;
}
//-------------------------------------------------------------------------
// Internal variable for the property value.
private var _menu:Menu;
public function get menu():Menu
{
return _menu;
}
public function set menu(value:Menu):void
{
_menu = value;
}
//-------------------------------------------------------------------------
private var _data:Object;
[Bindable("dataChange")]
public function get data():Object {
return _data;
}
public function set data(value:Object):void {
_data = value;
dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
}
//-------------------------------------------------------------------------
private function get borderMetrics():EdgeMetrics
{
return EdgeMetrics.EMPTY;
}
//-------------------------------------------------------------------------
private function renderComponent(event:FlexEvent):void
{
if(_data != null && _data != "null")
{
textField.htmlText = data.label;
invalidateProperties();
invalidateSize();
invalidateDisplayList();
}
}
//-------------------------------------------------------------------------
private function buttonClick(event:Event):void
{
mx.controls.Alert.show("button click");
}
//-------------------------------------------------------------------------
override protected function createChildren():void
{
super.createChildren();
// Create the TextField that displays the tooltip text.
if (!textField)
{
textField = new UITextField();
textField.autoSize = TextFieldAutoSize.LEFT;
textField.mouseEnabled = false;
textField.multiline = true;
textField.selectable = false;
textField.wordWrap = true;
textField.styleName = this;
addChild(textField);
}
}
//-------------------------------------------------------------------------
override protected function measure():void
{
super.measure();
var bm:EdgeMetrics = borderMetrics;
var leftInset:Number = bm.left + getStyle("paddingLeft");
var topInset:Number = bm.top + getStyle("paddingTop");
var rightInset:Number = bm.right + getStyle("paddingRight");
var bottomInset:Number = bm.bottom + getStyle("paddingBottom");
var widthSlop:Number = leftInset + rightInset;
var heightSlop:Number = topInset + bottomInset;
textField.wordWrap = false;
if (textField.textWidth + widthSlop > this.maxWidth)
{
textField.width = this.maxWidth - widthSlop;
textField.wordWrap = true;
}
measuredWidth = textField.width + widthSlop;
measuredHeight = textField.height + heightSlop;
this.parent.parent.height = this.parent.height = this.height = measuredHeight + 25;
this.parent.parent.width = this.parent.width = this.width = measuredWidth;
createAdditionalContent(measuredWidth, measuredHeight);
}
private function createAdditionalContent(measuredWidth:Number, measuredHeight:Number):void
{
clickText = new LinkButton();
clickText.label = "More Info";
clickText.width = 70;
clickText.height = 18;
clickText.setStyle("fontSize", 9);
clickText.setStyle("color", "blue");
clickText.buttonMode = true;
clickText.visible = true;
clickText.y = measuredHeight;
clickText.x = measuredWidth - clickText.width - 8;
clickText.addEventListener(MouseEvent.CLICK, dispatchClick);
addChild(clickText);
}
private function dispatchClick(e:Event):void
{
this.dispatchEvent(new Event("buttonClicked", true))
}
}
}