put icon at left of each button in spark ButtonBar flex 4 - flex4

hello all i have the following:
<s:ButtonBar id="tabs" y="15" left="0" height="31"
change="VideosMenuBar_changeHandler(event)" requireSelection="true">
<s:layout>
<s:HorizontalLayout gap="1" columnWidth="180" variableColumnWidth="false"
/>
</s:layout>
<s:ArrayCollection>
<fx:String>Latest Videos</fx:String>
<fx:String>Last Week Videos</fx:String>
<fx:String>Last Month Videos</fx:String>
</s:ArrayCollection>
</s:ButtonBar>
can anyone tell me how can i embed an icon to the left of each button of this (spark)ButtonBar?? I have searched all the web!
Thanks beforehand!

Create a skin class for the ButtonBar (e.g. CustomButtonBarSkin)
<s:ButtonBar id="tabs" y="15" left="0" height="31"
skinClass="CustomButtonBarSkin"
change="VideosMenuBar_changeHandler(event)" requireSelection="true">
<s:layout>
<s:HorizontalLayout gap="1" columnWidth="180" variableColumnWidth="false"
/>
</s:layout>
<s:ArrayCollection>
<fx:String>Latest Videos</fx:String>
<fx:String>Last Week Videos</fx:String>
<fx:String>Last Month Videos</fx:String>
</s:ArrayCollection>
</s:ButtonBar>
In the skin class look for the part where the buttons are defined as components, and change the skinClass attribute of the ButtonBarButton's to a custom skin class (e.g. CustomButtonBarButtonSkin).
<fx:Component id="firstButton">
<!-- <s:ButtonBarButton skinClass="spark.skins.spark.ButtonBarFirstButtonSkin" /> -->
<s:ButtonBarButton skinClass="CustomButtonBarButtonSkin" />
</fx:Component>
[...]
The custom ButtonBar skin class is based on spark.skins.spark.ButtonBarFirstButtonSkin, spark.skins.spark.ButtonBarMiddleButtonSkin or spark.skins.spark.ButtonBarLastButtonSkin.
In the custom ButtonBarButton skin class, you can add components as you wish. In the case of an image to he left, the class would look something like this.
<!-- layer 8: text -->
<!--- #copy spark.components.supportClasses.ButtonBase#labelDisplay -->
<s:Image source="#Embed('bricks.png')" />
<s:Label id="labelDisplay"
textAlign="center"
verticalAlign="middle"
maxDisplayedLines="1"
horizontalCenter="0" verticalCenter="1"
left="10" right="10" top="2" bottom="2">
</s:Label>!
And this it how it looks

Related

Flex Image Disappears

I am actually just learning flex, and i am getting confused with some parts. The problem is that the background image i have set in the skin works fine until i add more elements, it then just becomes a white background rather than laying the elements over the top.
I am starting to think im misunderstanding how this works. I don't understand why i need to have <s:Group id="contentGroup" /> for the image to show in the first place...this just seems like a redundant tag?
Here is the main code and the skin:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="800" height="523" maxWidth="800" maxHeight="523" initialize="httpService.send()" showStatusBar="false" backgroundColor="white" backgroundAlpha="1">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
public var returnData:ArrayCollection;
protected function httpService_handler(event:ResultEvent):void{
returnData = event.result.people.person;
}
]]>
</fx:Script>
<fx:Style>
#namespace s "library://ns.adobe.com/flex/spark";
#namespace mx "library://ns.adobe.com/flex/mx";
</fx:Style>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<s:HTTPService id="httpService" url="" result="httpService_handler(event)" />
</fx:Declarations>
<s:BorderContainer borderVisible="false" mouseDown="nativeWindow.startMove();" skinClass="MainStyle" width="800" height="523" id="container" >
<s:HGroup left="100" top="100" id="newsSlider" width="100" height="100">
<s:Label>
<s:text>Test</s:text>
</s:Label>
</s:HGroup>
</s:BorderContainer>
</s:WindowedApplication>
<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<!-- host component -->
<fx:Metadata>
[HostComponent("spark.components.BorderContainer")]
</fx:Metadata>
<!-- states -->
<s:states>
<s:State name="disabled" />
<s:State name="normal" />
</s:states>
<!-- SkinParts
name=contentGroup, type=spark.components.Group, required=false
-->
<s:Group id="contentGroup" width="800" height="523">
<s:BitmapImage id="bg" source="#Embed('/School Catchup/libs/images/App-BG8.png')" scaleMode="stretch" left="0" top="0" right="0" bottom="0" width="800" height="523" />
</s:Group>
</s:Skin>
contentGroup is the only "skinPart" of the SkinnableContainer component, which is the base class for BorderContainer. It's not a required skinpart (the compiler would've thrown you an error otherwise in your previous version where you didn't have the skinpart in your skin).
What is a skinPart?
It's a contract between the host component and its skin. Essentially the host component is instructing the skin (through metadata) that it needs this and this and that element (skin part) in order to function correctly. Some of these elements are absolutely required for the component to function, some are optional.
What is the contentGroup skinpart?
It's the container element to which SkinnableContainer will add its nested elements. As an example:
<s:SkinnableContainer>
<s:Label text="hello"/>
</s:SkinnableContainer>
behind the scenes, the Label instance will be added to the contentGroup skinpart of SkinnableContainer's skin.
So how do I get my example to work?
As you can see from what I explained before, the contentGroup element is just a placeHolder in the skin. If you want to add "chrome" to your custom component, add it outside that Group:
<s:BitmapImage id="bg" source="#Embed('/School Catchup/libs/images/App-BG8.png')" scaleMode="stretch" left="0" top="0" right="0" bottom="0" width="800" height="523" />
<s:Group id="contentGroup" width="800" height="523"/>
This will display the image behind the contentGroup and your Labels will now be added to it without removing the BitmapImage that you declared in there.
This is just a short explanation of the skinning mechanism in the context of your needs. I suggest you do some research on this specific topic to really understand how it works.

Filters and Gradient colors not getting applied simultaneously for button skin

I have created a sample desktop app using Flex 4 in flash builder 4 wherein I am using a button inside BorderContainer.
I have applied skin to button which includes Dropdownshadow,glow filter,bevel-filter and gradient colors.
But I am facing a problem with use of filters and gradient fill simultaneously.
When using filters gradient fill doesnt show up and vice-versa.
Please let me know where I am making mistake.
This is the main.mxml code:
<s:BorderContainer backgroundColor="#003C7B" verticalCenter="0" horizontalCenter="0" height="350" width="450">
<s:Button id="btn" label="Select" color="white" verticalCenter="0" skinClass="BlueButtonSkin" horizontalCenter="0"/>
</s:BorderContainer>
The skin class code for filters and gradient fill is as follows:
<s:Rect id="backgroundAndShadow" left="0" right="0" top="0" bottom="0" radiusX="5" radiusY="5"
topLeftRadiusX="5" topLeftRadiusY="5" topRightRadiusX="5" topRightRadiusY="5"
bottomLeftRadiusX="5" bottomLeftRadiusY="5" bottomRightRadiusX="5" bottomRightRadiusY="5">
<s:fill>
<s:LinearGradient rotation="90">
<s:GradientEntry color="#00366E"/>
<s:GradientEntry color="#013A8B" />
</s:LinearGradient>
</s:fill>
<s:filters>
<s:GlowFilter alpha="0.9" color="#ffffff" inner="false" knockout="true" blurX="8" blurY="8" />
<s:BevelFilter angle="270" distance="5" />
</s:filters>
</s:Rect>
<s:RectangularDropShadow id="dropShadow" blurX="8" blurY="8" alpha="0.5" distance="5" tlRadius="5" trRadius="5" blRadius="5" brRadius="5"
angle="45" color="#000000" left="2" top="0" right="0" bottom="0"/>
<s:Rect id="border" left="0" right="0" top="0" bottom="0" width="75" height="15"
topLeftRadiusX="5" topLeftRadiusY="5" topRightRadiusX="5" topRightRadiusY="5"
bottomLeftRadiusX="5" bottomLeftRadiusY="5" bottomRightRadiusX="5" bottomRightRadiusY="5">
<s:stroke>
<s:SolidColorStroke joints="bevel" caps="round" color="#84C2F2" weight="0.3" alpha="0.3"/>
</s:stroke>
</s:Rect>
<s:Label id="labelDisplay"
textAlign="center"
verticalAlign="middle"
maxDisplayedLines="2"
horizontalCenter="0" verticalCenter="0"
left="10" right="10" top="2" bottom="2">
</s:Label>
Any suggestions on this?
I am attaching the required look for button for reference:
In your <s:GlowFilter /> you have set the knockout property to true. So when applying that filter, it literally knocks out the contents of the item that the filter is applied to. Remove that property altogether or you can set it to false, which is the default.
Here's what the GlowFilter documentation says for the knockout property:
Specifies whether the object has a knockout effect. A knockout effect
makes the object's fill transparent and reveals the background color
of the document. The value true specifies a knockout effect; the
default value is false (no knockout effect).
Well,finally I have done it...
Played with the code and found this code works fine with what is required:
<s:Rect id="backgroundAndShadow2" left="0" right="0" top="0" bottom="0"
topLeftRadiusX="5" topLeftRadiusY="5" topRightRadiusX="5" topRightRadiusY="5"
bottomLeftRadiusX="5" bottomLeftRadiusY="5" bottomRightRadiusX="5" bottomRightRadiusY="5">
<s:fill>
<s:SolidColor color="#4B7CB6" alpha="0.5"/>
</s:fill>
<s:filters>
<s:DropShadowFilter blurX="5" blurY="5" quality="3" strength="0.65" distance="4" />
<s:GlowFilter blurX="7" blurY="7" quality="3" color="#004DAF"/>
<s:BevelFilter blurX="1" blurY="1" quality="3" strength="2" highlightColor="#9FC7F5" angle="60" distance="1"/>
<s:BlurFilter blurX="1.5" blurY="1.5"/>
</s:filters>
</s:Rect>
<s:Rect id="backgroundAndShadow" left="1.5" right="1.5" top="1.5" bottom="1.5"
topLeftRadiusX="5" topLeftRadiusY="5" topRightRadiusX="5" topRightRadiusY="5"
bottomLeftRadiusX="5" bottomLeftRadiusY="5" bottomRightRadiusX="5" bottomRightRadiusY="5">
<s:fill>
<s:LinearGradient scaleX="51" rotation="90">
<s:GradientEntry ratio="0" color="#013465"/>
<s:GradientEntry ratio="0.32156863" color="#013A7F"/>
<s:GradientEntry ratio="1" color="#003990"/>
</s:LinearGradient>
</s:fill>
<s:filters>
<s:DropShadowFilter inner="true" angle="-130" blurX="2" blurY="0.8" strength="0.5" color="#00275C" alpha="0.8"/>
</s:filters>
</s:Rect>
<s:Label id="labelDisplay"
textAlign="center"
verticalAlign="middle"
maxDisplayedLines="2"
horizontalCenter="0" verticalCenter="0"
left="10" right="10" top="2" bottom="2">
</s:Label>
Modified the skinclass and got the results!

Zk how to reach included .zul page component by id?

I can't reach component by id in the included .zul page. I have one main.zul with a controller and I need to get a component in included zul page through the java controller class, but it returns null.
I know the included method creates new id space but is there any way to get this component?
UPDATE
Here is my code:
the main zul page
<?page title="DealerVizard.zul"?>
<?page id="main" ?>
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" arg0="./Dealer" ?>
<zk>
<style src="/resources/css/default.css" />
<window id="Dealer" class="index"
apply="com.i2i.prm.controller.IndexController">
<div class="content" width="100%">
<tabbox id="tb" forward="onSelect=onSelect">
<tabs id="tabs">
<tab id="info" label="INFO" />
<tab id="create" label="CREATE" />
<tab id="edit" label="EDIT" />
<tab id="test" label="TEST PANEL(LIST BOX)" />
</tabs>
<tabpanels>
<tabpanel id="DealerInfo">
<include id="DealerInfoContent"
src="View/Dealer/DealerInfo.zul" />
</tabpanel>
<tabpanel id="DealerCreate">
<include id="DealerCreateContent"
src="View/Dealer/DealerCreate.zul" />
</tabpanel>
<tabpanel id="DealerEdit">
<include id="DealerEditContent"
src="View/Dealer/DealerEdit.zul" />
</tabpanel>
<tabpanel id="PagingListBox">
<include id="PagingListBoxContent" // Included here
src="View/TEST/PagingListBox.zul" />
</tabpanel>
</tabpanels>
</tabbox>
</div>
</window>
</zk>
PagingListBox.zul (Included page)
<?page id="list" ?>
<zk>
<grid width="100%">
<columns>
<column label="" />
</columns>
<rows>
<row>
<listbox id="listModel" width="100%" height="100%"
visible="true" span="true" pagingPosition="top" rows="20"
selectedItem="#{DealerController.selected}"
model="#{DealerController.userList}"
forward="onSelect=//main/Dealer.onSelect">
<auxhead>
<auxheader colspan="1">
<textbox
value="#{DealerController.searchUser.name}" maxlength="9"
id="searchCO_ID" forward="onChanging=//main/Dealer.onSearch"
width="100%">
</textbox>
</auxheader>
<auxheader colspan="1">
<textbox
value="#{DealerController.searchUser.surname}" maxlength="21"
id="searchMSISDN" forward="onChanging=//main/Dealer.onSearch"
width="100%">
</textbox>
</auxheader>
<auxheader colspan="1">
</auxheader>
</auxhead>
<listhead>
<listheader label="Name"
sort="auto(UPPER(name))" />
<listheader label="Surname"
sort="auto(UPPER(surname))" />
<listheader label="Delete ?" />
</listhead>
<listitem self="#{each=USERLIST}">
<listcell>
<label value="#{USERLIST.user.name}" />
<textbox
value="#{DealerController.tmpUser.name}" visible="false" />
</listcell>
<listcell>
<label value="#{USERLIST.user.surname}" />
<textbox
value="#{DealerController.tmpUser.surname}" visible="false" />
</listcell>
<listcell>
<button label="Update"
forward="onClick=//main/Dealer.onUpdate" visible="false" />
<button image="icons/edit-delete.png"
label="Delete" forward="onClick=//main/Dealer.onDelete"
width="100%" disabled="true" />
<button label="Save"
forward="onClick=//main/Dealer.onSave" visible="false" />
<button label="Cancel"
forward="onClick=//main/Dealer.onCancel" visible="false" />
</listcell>
</listitem>
</listbox>
<paging id="pagingData" pageSize="20" />
</row>
</rows>
</grid>
</zk>
IndexCOntroller.java
public class IndexController extends GenericForwardComposer {
private List<User> userList = new ArrayList<User>() ;
AnnotateDataBinder binder;
Tabbox tb;
Window Dealer;
private int pageCount=0;
#Override
public void doAfterCompose(Component comp) throws Exception {
// TODO Auto-generated method stub
super.doAfterCompose(comp);
comp.setVariable(comp.getId() + "Controller", this, true);
binder = (AnnotateDataBinder) Dealer.getVariable("binder", true);
System.out.println(Path.getComponent("//list/listModel"));
}
public IndexController() {
// TODO Auto-generated constructor stub
}
}
Normally I wouldn't recommend using Path.getComponent() way to access other components as your application code becomes tightly coupled with your component structure in your view page.
In your case you simplest way is to use AbstractComponent#getFellow(String compId) method so for eg.
Include inc = (Include) Dealer.getFellow("PagingListBoxContent");
Listbox listModel = (Listbox) inc.getFellow("listModel");
System.out.println(listModel);
So in future even if you insert any other component in your ZUML page before your listbox your code will still work.
UPDATE: BTW there was an interesting blogpost on this very topic on ZK blog recently
if your include have id, you can use dollar sign to get the inner components
<zk>
<include id="inc" src="test.zul />
</zk>
test.zul
<zk>
<label id="lab1" value="test1" />
</zk>
you can use "inc$lab1" get the label in test.zul
You can access any component in any other id space using zscript or java. if it is on the same page, but different window then (component B in window A):
Path.getComponent("/A/B");
if it is on a different page then (component B in window A on page P):
Path.getComponent("//P/A/B");
You can find documentation here: http://books.zkoss.org/wiki/ZK%20Developer%27s%20Reference/UI%20Composing/ID%20Space
You can add in your IndexController.java:
...
private Include DealerInfoContent;
...
this way you can access the included component within the parent composer.
(I would suggest to use camelCase ids for it, though).

Hgroup - how can I change order of elements?

When I create an HGroup and add elements to it, it adds the elements from left to right.
How can I change it to add Elements from right to left?
It sounds like you want to have the same controls and code as in usual MXML but with orientation of elements from right to left. So you need Flex SDK 4.1 and its Layout Mirroring feature. You can refer to the documentation how to use it.
This is the quick sample code:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script>
<![CDATA[
[Bindable]
private var currentDirection:String = "ltr";
]]>
</fx:Script>
<fx:Declarations>
<s:RadioButtonGroup change="currentDirection = selectorsGroup.selectedValue.toString()" id="selectorsGroup" />
</fx:Declarations>
<mx:VBox horizontalCenter="0" verticalCenter="0">
<s:HGroup id="controls" layoutDirection="{currentDirection}">
<s:Button label="1" />
<s:Button label="2" />
</s:HGroup>
<s:HGroup id="selectors">
<s:RadioButton group="{selectorsGroup}" label="LTR" selected="true" value="ltr" />
<s:RadioButton group="{selectorsGroup}" label="RTL" value="rtl" />
</s:HGroup>
</mx:VBox>
</s:Application>

Flex Component using global variable

I am using Flash Builder 4 Burrito Preview - builing a Mobile Application. I have a custom component called footer.mxml. That footer has 4 buttons, and one of them has a lable that is bound to cartValue. I am trying to maintain a global variable called cartValue within all views and footer component.
footer.mxml
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="100%" height="64" chromeColor="#000000" fontSize="10">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<mx:CurrencyFormatter id="currencyFormatter"
currencySymbol="$"
useThousandsSeparator="true"
precision="2" />
</fx:Declarations>
<fx:Script>
<![CDATA[
[Bindable]
public var cartValue:int;
]]>
</fx:Script>
<s:HGroup width="100%" contentBackgroundColor="#000000" paddingBottom="0" paddingLeft="0"
paddingRight="0" paddingTop="0">
<s:Button x="0" y="624.5" width="25%" height="64" label="Account" chromeColor="#2259AA"
enabled="true" fontSize="10" fontWeight="bold" icon="#Embed('assets/user.png')"/>
<s:Button x="121" y="624.5" width="25%" height="64" label="Orders" chromeColor="#2259AA"
fontSize="10" icon="#Embed('assets/doc_lines_stright.png')"/>
<s:Button x="241" y="624.5" width="25%" height="64" label="Help" chromeColor="#2259AA"
fontSize="10" icon="#Embed('assets/spechbubble.png')"/>
<s:Button x="360" y="624.5" width="25%" height="64" label="{currencyFormatter.format(cartValue)}" chromeColor="#2259AA"
fontSize="10" icon="#Embed('assets/shop_cart.png')"/>
</s:HGroup>
</s:Group>
RincoTest.mxml
<s:MobileApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
backgroundColor="#000000" firstView="views.RincoTestHome"
>
<fx:Style source="RincoTest.css"/>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
[Bindable]
public var cartValue:int;
]]>
</fx:Script>
<s:titleContent>
<s:Image left="1" top="3" width="173" height="75" backgroundAlpha="1.0" smooth="true"
source="assets/iphone_large.png"/>
</s:titleContent>
<s:navigationContent>
<mx:Spacer width="10" height="82"/>
</s:navigationContent>
</s:MobileApplication>
And this is how I am implementing it
<components:footer x="1.65" y="614.95" width="100%" height="64" cartValue="{cartValue}"/>
I have tried to bind Application.application.cartValue and
MobileApplication.application.cartValue. Neither of them work.
If there is a better way to maintain a cartValue across the entire application please let me know. This is my first attempt with Flex.
Thanks,
Ernie
Use a static variable in the component.
Reference it as ComponentName.staticVar. Usually, everything that needs to know about the global already knows about (e.g. imports) the component file.
Cheers
Another solution is using a singleton pattern: a single instance that everything references through a static accessor.
The effect is about the same. The only advantage to a static reference to an instance over static properties is that the instance can be part of an inheritance and can fulfill an interface.
I've also had some intermittent problems with binding to static values, but that might have been a previous version, PEBCAK, etc.
Cheers

Resources