I have a small problem which is hopefully nothing for you. :-)
I have a tabbar in mxml-Form. It looks like that:
<mx:TabBar id="tabBar_" itemClick="clickEvt(event);" selectedIndex="1" creationComplete="check()">
<mx:dataProvider>
<mx:Object label="Components" data="{ComponentTabOverview}"/>
<mx:Object label="Products" data="{ProductTabOverview}"/>
</mx:dataProvider>
</mx:TabBar>
Now I have the problem that I have to check after creating the tabbar, from which state the tabbar is created.
And if its created from an particular state, the first tab has to be disabled.
I did that as follows:
public function check():void {
if(checkstate_){
tabBar_.getChildAt(0).enabled= false;
}
}
Unfortunately it doesn't work.
Can somebody help me out?
Thanks!!!!
Mike
There seems to be an undocumented (it's marked #private in the ASDOCs) property in the NavBar component called enbaledField. The TabBar component extends NavBar at some point in it's class hierarchy.
Here is the code from the Apache Flex github repo (included just so you can read the ASDOC comments):
/**
* #private
* Storage for the enabled property.
*/
private var _enabledField:String = "enabled";
[Bindable("enabledFieldChanged")]
[Inspectable(category="Data")]
/**
* Name of the the field in the <code>dataProvider</code> object
* to use as the enabled label.
*
* #default "enabled"
*
* #langversion 3.0
* #playerversion Flash 11.1
* #playerversion AIR 3.4
* #productversion Flex 4.10
*/
public function get enabledField():String
{
return _enabledField;
}
So theoretically (I don't have Flex installed either), if the elements in your dataProvider have a property called enabled you can disable individual buttons in the TabBar.
Alternatively, if you'd like to use some other field in the dataProvider elements to indicate that the button should be enabled/disabled, you can set a new value on the enableField property.
The caveat seems to be that the ASDOC says this was first included in Flex 4.10. But I think that is odd since this is an older MX component. However, it could be that this property was indeed added in Flex 4.10.
If it's true, that this is only in Flex 4.10, then you could copy the respective bits of code and implement it yourself as #zeus suggested. In particular make note of the private method createNavChildren() in the NavBar class where the magic happens:
//Check for enabled field and assign it to the individual button if it exists.
if (_enabledField != "" && item.hasOwnProperty(_enabledField) == true)
{
navItem.enabled = Boolean(item[_enabledField]);
}
else
{
navItem.enabled = enabled;
}
Here is a link to NavBar class in the github repo that has all of the above code.
Related
By default PrimeFaces DefaultScheduleEvent have the following attributes
Title, Description, start date, end date etc.
My question is how to include one or more custom attribute in schedule event.
A not so technical workaround that I used to generate a customized detail dialog is to determine the object type through styleClasses, for example:
public ScheduleModel getEventModel() {
if (eventModel == null) {
eventModel = new DefaultScheduleModel();
/*
* Just fill your model with a couple things, setting a specific styleClass
* for each type. Btw, you can also use this to give a specific appearance
* to each data type
*/
for(Activity act: myActivities){
event = new DefaultScheduleEvent(act.getActName(), act.getStartDate(), act.getEndDate(),"activity");
eventModel.addEvent(event);
}
for(Meeting meet : myMeetings){
event = new DefaultScheduleEvent(meet.getMeetPurpose(), meet.getStartDate(), meet.getEndDate(),"meeting");
eventModel.addEvent(event);
}
}
return eventModel
}
public void onEventSelect(SelectEvent selectEvent) {
if(selectEvent.getStyleClass().contains("activity")){
/*
* Search for object on DB and do stuff.
*/
}
}
In my onEventSelect you can use a searchForActivity(event.getTitle(), event.getStartDate(), event.getEndDate()) on your Session Bean to get all the info related to this specific object. Then you can build a regular view with the retrieved object.
I know this might not be the best way to achieve a "custom event", but will allow you to create whatever class you need and build views based on what you want to show to the user.
Hope it helps, kind regards :)
In a MvvmCross app, I have a page with the classic chat behavior (WhatsApp like): this page shows the history of messages exchanged between two users with the last message at the bottom of the list.
I've successfully implemented the view in Windows Phone 8.1, but I'm struggling with a problem in Android.
I'll give you a short introduction and description of my problem and next I'll go through technical details.
INTRODUCTION
Actually, my need is to apply different style to messages sent by different users: tipically align left messages sent from other user and align right messages sent by me (I do this through the weight property); I need to apply a different drawable background and set different gravity property also.
I use custom binding because, AFAIK, those properties cannot be binded with classic binding: local:MvxBind="Gravity MyPropery" doesn't work because there is no Gravity property.
So, I have of course two axml files:
the first one contains the Mvx.MvxListView
the second one contains the item template for MvxListView
And I've created three different custombinding (for Background, Gravity and Weight) following these guides:
http://slodge.blogspot.it/2013/06/n28-custom-bindings-n1-days-of-mvvmcross.html
In MvvmCross how do I do custom bind properties
THE PROBLEM
I want that, when a user opens the chat View, the list widget shows automatically the last message. To accomplish this, I scroll programmatically the list to the last message and this seems to be the problem.
If I don't scroll programmatically, when I open the page and scroll manually to the end of the page, all custom bindings are applied successfully: I can see messages aligned right and left, with correct background and weight applied.
If I force the scroll programmatically, when I open the page I see a strange behavior: all the messages are present (classic binding, such as Text property, have been successfully applied), but custom bindings are missing. All the messages have the same background and are all left aligned.
BUT, if I scroll manually up and down, the custom binding are processed and the messages are displayed with right style.
DEBUG ANALYSIS
To debug the behaviour I've put a simple static counter in a custom binding procedure to track every time the function is processed.
public class LinearLayoutWeightTargetBinding : MvxAndroidTargetBinding
{
public static int debugCounter = 0;
public LinearLayoutWeightTargetBinding(object target) : base(target)
{
}
protected LinearLayout MyTarget
{
get { return (LinearLayout)Target; }
}
public override Type TargetType { get { return typeof(bool); } }
protected override void SetValueImpl(object target, object value)
{
var ll = (LinearLayout)target;
var itsMe = (bool)value;
var weight = itsMe ? (float)20.0 : (float)5.0;
var layoutParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WrapContent, weight);
ll.LayoutParameters = layoutParams;
Log.Debug("MeeCHAT", string.Format("LinearLayoutWeightTargetBinding::SetValueImpl::ItsMe:{0} - counter:{1}", itsMe, ++debugCounter));
}
public override MvxBindingMode DefaultMode { get {return MvxBindingMode.TwoWay;} }
}
By this way I saw that actually by scrolling up and down the custom bindings are applied (debugCounter increases correctly).
BUT when I apply the programmatically scroll, only the first 10 items are processed by the custom bindings and this seems the reason why I see the messages without the right style. Because I have a long list, only the first 10 items are processed but they are not visible (they are out of the visible area) and the visibile items have not been processed.
TECHNICAL DETAILS
Here are some details related to technical aspects of my app. I try to give you all important aspects.
ORGANIZATION OF THE VIEWS
By following the approach described by Greg Shackles in this article http://gregshackles.com/presenters-in-mvvmcross-navigating-android-with-fragments/ I have just one general Activity for the app and one Fragment for each View; then through a Presenter is possible to activate the right ViewModel and manage the stack of the navigation.
The Fragment for the View where I have the Mvx.MvxListView widget is
public class MyMatchersChatView : MvxFragment
{
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var ignore = base.OnCreateView(inflater, container, savedInstanceState);
var result = this.BindingInflate(Resource.Layout.MyMatchersChatView, null);
var headerFrame = result.FindViewById<FrameLayout>(Resource.Id.headerFrameMyMatchersChatView);
var headerWidget = new HeaderWidget() { ViewModel = this.ViewModel };
var tran = ChildFragmentManager.BeginTransaction();
tran.Add(headerFrame.Id, headerWidget, "headerMyMatchersChat");
tran.Commit();
var listView = result.FindViewById<MvxListView>(Resource.Id.messagesList);
listView.SetSelection(listView.Adapter.Count - 1); // Scroll to the end of the list
return result;
}
}
The statement listView.SetSelection(listView.Adapter.Count - 1); force the list to scroll to the end.
Last two things: how the custom bindings are registered and how are applied in axml file.
REGISTRATION OF CUSTOM BINDING
In Setup.cs I have:
protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
{
base.FillTargetFactories(registry);
registry.RegisterFactory(new MvxCustomBindingFactory<LinearLayout>("CustomWeight",
(b) => new LinearLayoutWeightTargetBinding(b)));
}
APPLYING OF CUSTOM BINDING
In my axml I have:
<LinearLayout
android:orientation="horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
local:MvxBind="CustomWeight IsCurrentUser">
LISTVIEW AND VIEWMODEL
Here is the code of ListView
<Mvx.MvxListView
android:id="#+id/messagesList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
local:MvxBind="ItemsSource MyMessages"
local:MvxItemTemplate="#layout/mymatcherschatview_itemtemplate" />
and the property in ViewModel
private IEnumerable<MyMatchMessageModel> _myMessages;
public IEnumerable<MyMatchMessageModel> MyMessages
{
get { return _myMessages; }
set
{
_myMessages = value;
RaisePropertyChanged(() => MyMessages);
}
}
ENVIRONMENT
Finally, here is my environment:
Visual Studio 2015
MvvmCross 3.5.1
Core targets: .NET Framework 4.5, Windows 8, ASP.NET Core 5.0, Windows Phone 8.1, Xamarin.Android, Xamarin.iOS, Xamarin.iOS (Classic)
The Android app target is API Level 19 (Xamarin.Android v4.4 Support)
Xamarin 3.11.1450.0
Xamarin.Android 5.1.6.7
Someone can help me to understand if I'm doing something wrong?
Thanks for reading and for any help!
>>EDIT 1<<
I've changed my layout by adding stackFromBottom and transcriptMode properties and by removing the scrolling to below programmatically in Fragment obtaining an auto-scroll behavior, but the problem still remains: to see messages with correct style I have to manually scroll up and down (to activate the custom bindings)
Here is the new axml...
<Mvx.MvxListView
android:id="#+id/messagesList"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stackFromBottom="true"
android:transcriptMode="alwaysScroll"
local:MvxBind="ItemsSource MyMessages"
local:MvxItemTemplate="#layout/mymatcherschatview_itemtemplate" />
...and the new code in Fragment
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var ignore = base.OnCreateView(inflater, container, savedInstanceState);
var result = this.BindingInflate(Resource.Layout.MyMatchersChatView, null);
var headerFrame = result.FindViewById<FrameLayout>(Resource.Id.headerFrameMyMatchersChatView);
var headerWidget = new HeaderWidget() { ViewModel = this.ViewModel };
var tran = ChildFragmentManager.BeginTransaction();
tran.Add(headerFrame.Id, headerWidget, "headerMyMatchersChat");
tran.Commit();
return result;
}
First thing I would do is to make sure that your custom binding is always getting called.
Set a breakpoint on the SetValueImpl() method and check it´s getting called on those problematic items. If that happens, then the issue relies on the view no getting updated for any reason and you should work on that. If it doesn´t break, you will know for sure it´s a custom binding problem (possibly a bug) in MvxAdapter.
If you find out it´s the second one. I would suggest getting rid of your custom binding and creating your own ChatListAdapter : MvxAdapter as follows:
public class CoolChatListAdapter : MvxAdapter
{
public CoolChatListAdapter(Context context, IMvxAndroidBindingContext bindingContext) : base(context, bindingContext)
{
}
protected override View GetBindableView(View convertView, object source, int templateId)
{
var item = source as MyMatchMessageModel;
var weight = item.IsCurrentUser ? (float) 20.0 : (float) 5.0;
var ll = (LinearLayout) convertView;
var layoutParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WrapContent, weight);
ll.LayoutParameters = layoutParams;
return base.GetBindableView(convertView, source, templateId);
}
}
Then, in your android view:
var adapter = new ChatListAdapter(this, (IMvxAndroidBindingContext)BindingContext);
_chatList = FindViewById<MvxListView>(Resource.Id.chat_list_view);
_chatList.Adapter = adapter;
I'm using #lends + #constructs + #augments for MooTools Class definitions (custom namespace variation), however I'm getting some inspection issues in PhpStorm in extending classes if I don't include an initialize in the extending class with a #constructs above it. Is it not possible in jsDoc to omit initialize in extending classes OR is PhpStorm inspection just not working correctly?
new Class('Validator.Generic',
/**
* #lends Validator.Generic
*/
{
/**
* #constructs
*/
initialize:function(){}
}
new Class('Validator.Regex',
/**
* #augments Validator.Generic
* #lends Validator.Regex
*/
{
//PhpStorm inspection reports unrecognized symbol Regex unless
//I add a method with #constructs here, even though the class
//it augments has a constructor
});
I've tried variations as well. It only works if I add an initialize to the extending class (e.g. Validator.Regex) along with a #constructs tag to the docblock. This of course is not ideal.
Try adding /** #class Validator.Regex */ above new Class('Validator.Regex')
#lena's answer partially works, but was still arbitrarily failing inspection in seemingly identical situations. I changed my approach and thought about the literal meanings of the tag names. Conclusion: '#class' is to define a type (pseudo statically), '#augments' and '#lends' in the context of a prototype based languages should then imply Instance extensions. This is intuitive in hind sight. All inspections now pass with the following syntax.
/**
* #class Validator.Regex
* #augments {Validator.Generic}
*/
new Class('Validator.Regex',
/**
* #lends {Validator.Regex}
*/
{}
);
As currently developing an mobile application with Flex Mobile, got to the point of finalising things and make some fine visual layout adjustments. As my Application is built in sections using TabbedViewNavigatorApplication i wanted to add and fine tune icons that appear in the TabbedViewNavigator #tabBar tabs. Well, that was one of those tasks that seems to take minutes, ending in searching Adobe api docs and googling around for hours, eventually to find the solution in days. Said so i want to post my solution, hoping that someone will need it and use it in their own specific situations.
The first thing to mention here is that Adobe per default, has an extensive help library for skinning spark components, but eventually and on the end - those examples often only scratch the surface of what is needed in specific situation and / or implementation.
At first i want to say that I avoid using mxml skins and always do my spark skinning job in AS3 classes using ClassReference. Seems to me that this approach is much more flexible, elegant and cleaner than over-spamming things in mxml. Although sometimes more harder to implement.
So your typical minimal TabbedViewNavigator Application looks like this:
<?xml version="1.0" encoding="utf-8"?>
<s:TabbedViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160" applicationComplete="onApplicationComplete(event)">
<fx:Style source="MyStyles.css" />
<fx:Script>
<![CDATA[
import spark.components.ViewNavigator;
private function onApplicationComplete(e:Event):void {
for each(var vn : ViewNavigator in this.navigators){
/// do something with your VN's ...
vn.icon = "./assets/myFaboulousIcon.png";
}
}
]]>
</fx:Script>
<s:ViewNavigator label="one" width="100%" height="100%" firstView="views.oneView"/>
<s:ViewNavigator label="two" width="100%" height="100%" firstView="views.twoView"/>
<s:ViewNavigator label="three" width="100%" height="100%" firstView="views.threeView"/>
</s:TabbedViewNavigatorApplication>
In this typical configuration you can access the ViewNavigator icon property and set it either in your mxml or from AS3 (eg. in the for loop above) eventually adding a switch statement to select different icons for each tab ... But that is where your story ends. ViewNavigator icon property is used when certain ViewNavigator is represented by a visual component. Which means that in your #tabBar the ViewNavigator is represented visually as a part of navigators stack, and is logical - in this situation it uses the icon specified.
Now let's suppose now you want to change the alpha or colorise your icons programatically, meaning you always use one set of icons but in different situations - you give them different visual properties, and one of those situations can be - their visual appeal in the application #tabBar.
The icon property is a path to the icon image file, and as a type is an generic Object. So you can't change alpha or do anything else with it. Neither icon property will give you any reference to the display object containing the icon itself or anything else you want for your juicy AS3 jonglery pokery ...
For such task we must do some nice spark skinning (in AS3) ;) So read the answer bellow
The first step is to add your css file from example above MyStyles.css (i always do skin class references from within css, found it easy to manage and change if needed) ...
/* MyStyle.css example */
.
.
s|TabbedViewNavigator #tabBar {
skinClass: ClassReference("com.myapp.skins.TabBarSkin");
}
.
.
You must now define your custom TabBarSkin class that can look something like this:
/* TabBarSkin Class */
package com.myapp.skins
{
import spark.skins.mobile.TabbedViewNavigatorTabBarSkin;
import spark.skins.mobile.supportClasses.ButtonBarButtonClassFactory;
import spark.components.ButtonBarButton;
public class TabBarSkin extends TabbedViewNavigatorTabBarSkin
{
public function TabBarSkin() {
super();
}
override protected function createChildren():void
{
if (!firstButton) {
firstButton = new ButtonBarButtonClassFactory(ButtonBarButton);
firstButton.skinClass = TabBarFirstTabSkin;
}
if (!lastButton) {
lastButton = new ButtonBarButtonClassFactory(ButtonBarButton);
lastButton.skinClass = TabBarLastTabSkin;
}
if (!middleButton) {
middleButton = new ButtonBarButtonClassFactory(ButtonBarButton);
middleButton.skinClass = TabBarLastTabSkin;
}
super.createChildren();
}
}
}
Not getting so much in details, you must know that this custom class TabBarSkin inherits from TabbedViewNavigatorTabBarSkin which has 3 skin classes for each of the significant tab positions / first / mid / last / in your #tabBar. In the most simple situation we must implement (extend) two of them / first / and / last -> as the / mid / position also uses the / last / skin, and in this case we don't need it separately implemented.
/* TabBarFirstTabSkin Class */
package com.myapp.skins
{
import spark.components.Group;
import spark.skins.mobile.TabbedViewNavigatorTabBarFirstTabSkin;
public class TabBarFirstTabSkin extends TabbedViewNavigatorTabBarFirstTabSkin
{
private var __iconGroup : Group = null;
public function TabBarFirstTabSkin() {
super();
}
override protected function layoutContents(unscaledWidth : Number, unscaledHeight : Number) : void {
super.layoutContents(unscaledWidth, unscaledHeight);
if(!__iconGroup) {
__iconGroup = getIconDisplay() as Group;
}
}
}
}
Same as for the / last / one:
/* TabBarLastTabSkin Class */
package com.myapp.skins
{
import spark.components.Group;
import spark.skins.mobile.TabbedViewNavigatorTabBarLastTabSkin;
public class TabBarLastTabSkin extends TabbedViewNavigatorTabBarLastTabSkin
{
private var __iconGroup : Group = null;
public function TabBarLastTabSkin() {
super();
}
override protected function layoutContents(unscaledWidth : Number, unscaledHeight : Number) : void {
super.layoutContents(unscaledWidth, unscaledHeight);
if(!__iconGroup) {
__iconGroup = getIconDisplay() as Group;
}
}
}
}
Finally, the __iconGroup member will now have reference to the Group visual component containing your icon! -> and which you defined in your ViewNavigator instance through mxml / or in AS3 code. Now we can go dirty ;) and do things like this for example:
.
.
.
var colorTransform : ColorTransform = new ColorTransform();
colorTransform.color = 0xFF3300;
colorTransform.alphaMultiplier = 0.85;
__iconGroup.transform.colorTransform = colorTransform;
.
.
.
Which will colorise your icon in red and give alpha 0.85. etc ... This is really the basics you can do with spark #tabBar skinning in Flex Mobile. Hope will help someone. Cheers.
I am using a combination of gwt and smart gwt. However i get the following eror whenever my page loads. please help me with fixing this. .
Please find the attached screenshot for the image of the popup error for the same
15:06:02.097 [ERROR] [detectfiles] 15:06:02.097:TMR5:WARN:Log:Error:
'Object required'
in /sc/modules/ISC_Core.js
at line 1782
[c]Element.getOffsetLeft(_1=>[DIVElement]{ID:isc_0})
[c]Element.getOffset(_1=>"left", _2=>[ImgButton ID:isc_ImgButton_0], _3=>undef, _4=>false, _5=>true)
Canvas.getLeftOffset(_1=>undef)
Canvas.getPageLeft()
Canvas.$414(null, undef)
[c]Page.handleEvent(_1=>null, _2=>"resize", _3=>undef)
[c]EventHandler.$78p(_1=>"landscape")
[c]EventHandler.$hr(_1=>undef)
callback(undefined=>undef)
"isc.EH.$hr()"
[c]Class.fireCallback(_1=>"isc.EH.$hr()", _2=>undef, _3=>Array[0], _4=>Obj{length:2}, _5=>true) on [Class Timer]
[c]Timer.$in(_1=>"$ir28")
anonymous()
"isc.Timer.$in('$ir28')"
com.smartgwt.client.core.JsObject$SGWT_WARN: 15:06:02.097:TMR5:WARN:Log:Error:
'Object required'
in /sc/modules/ISC_Core.js
at line 1782
[c]Element.getOffsetLeft(_1=>[DIVElement]{ID:isc_0})
[c]Element.getOffset(_1=>"left", _2=>[ImgButton ID:isc_ImgButton_0], _3=>undef, _4=>false, _5=>true)
Canvas.getLeftOffset(_1=>undef)
Canvas.getPageLeft()
Canvas.$414(null, undef)
[c]Page.handleEvent(_1=>null, _2=>"resize", _3=>undef)
[c]EventHandler.$78p(_1=>"landscape")
[c]EventHandler.$hr(_1=>undef)
callback(undefined=>undef)
"isc.EH.$hr()"
[c]Class.fireCallback(_1=>"isc.EH.$hr()", _2=>undef, _3=>Array[0], _4=>Obj{length:2}, _5=>true) on [Class Timer]
[c]Timer.$in(_1=>"$ir28")
anonymous()
"isc.Timer.$in('$ir28')"
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:105)
at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:292)
at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:546)
at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363)
at java.lang.Thread.run(Thread.java:662)
Here is a piece of code in which I am using TreeGrid inside a popup
private PopupPanel createConsoPopup() {
final PopupPanel consoPopup = new PopupPanel();
consoPopup.setAnimationEnabled(true);
consoPopup.setAutoHideEnabled(true);
VerticalPanel consoContent = new VerticalPanel();
VEPConsoTree consoTree = new VEPConsoTree(lineTreeNode, vepConsoTree);
vepConsoTree = consoTree.getCheckStationTree();
vepConsoTree.addSelectionChangedHandler(new SelectionChangedHandler() {
#Override
public void onSelectionChanged(SelectionEvent event) {
((TextBox)flexTable.getWidget(selectedRowNum, 0)).setText(vepConsoTree.getSelectedRecord().getAttribute("vepAreaName")+"_"+vepConsoTree.getSelectedRecord().getAttribute("checkStationName"));
consoPopup.hide();
}
});
consoContent.add(consoTree);
consoPopup.add(consoContent);
return consoPopup;
}
Following is my VEPConsoTree class:
package com.renault.veppwrstats.client;
import com.google.gwt.user.client.ui.Composite;
import com.smartgwt.client.types.TreeModelType;
import com.smartgwt.client.widgets.events.DrawEvent;
import com.smartgwt.client.widgets.events.DrawHandler;
import com.smartgwt.client.widgets.tree.Tree;
import com.smartgwt.client.widgets.tree.TreeGrid;
import com.smartgwt.client.widgets.tree.TreeNode;
public class VEPConsoTree extends Composite {
private TreeNode[] lineTreeNode;
private TreeGrid vepConsoTree;
//private DFConstantsForLocale constants = GWT.create(DFConstantsForLocale.class);
/**
* #param lineTreeNode
* #param vepConsoTree
*/
public VEPConsoTree(TreeNode[] lineTreeNode, TreeGrid vepConsoTree) {
super();
this.lineTreeNode = lineTreeNode;
this.vepConsoTree = vepConsoTree;
//Grid grid = chckStatRestrictPanel();
initWidget(vepConsoTree());
}
/**
* This function creates checkStation Restriction Panel(tree) along with
* Select/Unselect All button
*
* #return
*/
private TreeGrid vepConsoTree() {
return createTreeGrid();
}
/**
* This function creates CheckStation Restriction Tree
*
* #return {#link TreeGrid}
*/
private TreeGrid createTreeGrid() {
final TreeGrid chckTreeGrid = new TreeGrid();
chckTreeGrid.setHeight("269px");
chckTreeGrid.setWidth("250px");
chckTreeGrid.setData(createChkStationTree());
//chckTreeGrid.setSelectionAppearance(SelectionAppearance.CHECKBOX);
//chckTreeGrid.setShowPartialSelection(false);
//chckTreeGrid.setCascadeSelection(true);
chckTreeGrid.setFolderIcon(null);
chckTreeGrid.setNodeIcon(null);
chckTreeGrid.setShowConnectors(true);
chckTreeGrid.setShowHeader(false);
//addSelectionChangeHndler(chckTreeGrid);
chckTreeGrid.addDrawHandler(new DrawHandler() {
public void onDraw(DrawEvent event) {
chckTreeGrid.getTree().openAll();
}
});
vepConsoTree = chckTreeGrid;
return chckTreeGrid;
}
/**
* This function creates a basic tree
*/
private Tree createChkStationTree() {
Tree chckStationTree = new Tree();
chckStationTree.setModelType(TreeModelType.PARENT);
chckStationTree.setRootValue(1);
chckStationTree.setIdField("id");
chckStationTree.setOpenProperty("isOpen");
chckStationTree.setData(lineTreeNode);
chckStationTree.setParentIdField("parent");
return chckStationTree;
}
/**
* #return the vepConsoTree
*/
public final TreeGrid getCheckStationTree() {
return vepConsoTree;
}
/**
* #param vepConsoTree the vepConsoTree to set
*/
public final void setCheckStationTree(TreeGrid checkStationTree) {
this.vepConsoTree = checkStationTree;
}
/**
* #return the lineTreeNode
*/
public final TreeNode[] getLineTreeNode() {
return lineTreeNode;
}
/**
* #param lineTreeNode the lineTreeNode to set
*/
public final void setLineTreeNode(TreeNode[] lineTreeNode) {
this.lineTreeNode = lineTreeNode;
}
}
Short answer : don't mix GWT and SmartGWT when you can
Can I mix Smart GWT and GWT widgets?
Yes, with caveats.
Smart GWT has interoperability support that allows a Smart GWT widget
to be added to a GWT container and allows a GWT widget to be added to
a Smart GWT container, and it's appropriate to use this for:
incremental migration to Smart GWT, such as introducing singular,
sophisticated Smart GWT components like the Calendar or CubeGrid to an
existing GWT application
using sophisticated third-party GWT widgets within Smart GWT, where
Smart GWT doesn't have corresponding built-in functionality
However it does not make sense to freely intermix Smart GWT and GWT
(or other) components, that is, for example, you should not place GWT
widgets within a Smart GWT container that is in turn within a GWT
container. In general, don't intermix widgets unless the need for a
feature forces you to.
The reason for this is that there are limits to the maximum degree
that two Ajax widget kits (including GWT) can interoperate - there are
no standards that allow interoperability in the areas of management of
tab order, zIndex management, pixel-perfect layout, section 508
accessibility and multi-level modality.
Note that "bugs" reported when intermixing GWT and Smart GWT
inappropriately (that is, in contradiction to these guidelines) are
generally going to be marked WONTFIX, although we will revisit this in
the future if core GWT begins to support APIs that would allow better
interoperability.
If you really need to mix GWT and SmartGWT here are the guidelines from Isomorphic
Because Smart GWT's pixel-perfect layout and auto-sizing support goes
beyond the capabilities of simple CSS layout, components need to know
the actual pixel width they have been allocated by their parent
element; they cannot "flow into" an HTML element of unspecified size.
The issue here is that GWT's containers do not provide an API similar
to Smart GWT's Canvas.getInnerWidth(), which in Smart GWT can be used
by child components to find out the available space to draw themselves
in, and hence recursively lay out out their own children. Nor do GWT
containers fire events when they are resized, or when the available
width changes for various reasons (e.g. scrollbar(s) introduced, or
CSS style changes add borders and hence reduce space).
A lot of parent<->child coordination and signaling is required to
really create an extensible pixel-perfect layout system. Smart
GWT/SmartClient has implemented all the necessary hooks to allow a
third-party widget to be embedded inside a Canvas and participate in a
precise layout, but GWT is not there yet.
If you absolutely must place a Smart GWT interface inside a GWT
container and you want it to fill the container, the best approach is
to listen for a window-level resize event and run your own layout
calculations that ultimately call resizeTo() on your topmost Smart GWT
widget. All Smart GWT widgets nested under that topmost widget will
then handle layout normally.
NOTE: Don't bother trying to find a way to insert width:100% into
Smart GWT's rendered HTML, this won't work.
source : http://forums.smartclient.com/showthread.php?t=8159