Alternating row colors for GWT CellTable - gwt-2.2-celltable

I'm extending the GWT celltable, and I'd like to override the default row striping with my own styles. The documentation seems to indicate that the celltable should implement RowStyles interface, which I have:
#Override
public String getStyleNames(Object row, int rowIndex) {
if(rowIndex == 0 || rowIndex % 2 == 0)
return "even_row";
return "odd_row";
}
However, it's not applying the style - It's not even hitting the method. If I'm extending the GWT CellTable, then it should be calling this method to apply the row style, right?
Anyone have this working and can tell me what I'm missing...?

Have a look at this page, specifically the last post on the page. It gives a good example of how to do this.
Implement the RowStyles interface and call this:
this.setRowStyles(this);

Related

Custom layout inside FragmentGridPagerAdapter

I am trying to add a custom layout page within cards.
Here: https://developer.android.com/training/wearables/ui/2d-picker.html
explains that CardFragment can easily add a card by:
CardFragment fragment = CardFragment.create(title, text, page.iconRes);
now if I decided I want to have a custom layout, how do I add it instead of creating a CardFragment?
Check this image:
The third page is a full screen custom layout. How can I achieve this?
FragmentGridPagerAdapter can actually support any subclass of Fragment that you need to use. CardFragment is just a convenience for a standard wearable layout.
So, you can just create a custom Fragment with a simple layout (such as a full-size ImageView) and return it for the appropriate page index.
On getFragment(int row, int col) method from your FragmentGridPagerAdapter class, you can create as many fragments as you want.
you just need to test your row/col values in order to instantiate your fragment class in the correct position.
In your case, something like this:
public Fragment getFragment(int row, int col) {
Fragment fragment;
if (row == 0 && col == 2) {
fragment = new YourFullScreenFragment();
} else {
fragment = CardFragment.create(title, text, page.iconRes);
}
return fragment;
}
Cheers
CardFrame is probably that one that you are looking for - it very similar to CardFragment but you can implement your own layout to it. Also as matiash pointed you can use any fragment that you like in such structure.

How to simple overwrite showContextMenu on all columns of a grid?

If I overwrite showContextMenu on a grid it only add additional menu to the pop up menu when I click on a grid but do not click on any column. One way is to overwrite showContextMenu on all columns in grid but this solution does not looks right. Is there some better way how to insertItem to showContextMenu on all columns of a grid?
I am using AX 2012.
Standard code works only if grid is clicked but not a single column of a grid.
int ret,ii;
int myMenu = 2;
PopupMenu popupMenu = PopupMenu::create(_menuHandle);
FormListItem item;
;
deleteAttachment = popupMenu.insertItem('My menu');
ret = super(_menuHandle);
if(ret == myMenu)
{
//My code
}
return ret;
You need to use method registerOverrideMethod.
You can test how it works as follows. E.g. you have a form with a grid (property Name = 'Grid', AutoDeclaration = 'Yes'), and there are a few StringEdit controls in that grid.
1) Create following method in your form:
public void formControlContext(FormStringControl _formStringControl)
{
_formStringControl.context();
info(strFmt(#"Overridden context of control '%1'", _formStringControl.name()));
}
2) Override method init in your form:
public void init()
{
FormStringControl fsc;
int controlNum;
super();
for (controlNum = 1; controlNum <= Grid.controlCount(); controlNum++)
{
fsc = Grid.controlNum(controlNum);
fsc.registerOverrideMethod(methodStr(FormStringControl, context), identifierStr(formControlContext));
}
}
You only need to modify method 'formControlContext' according to your needs.
P.S. I just noticed you need to override method showContextMenu anot not context. The idea is the same - use registerOverrideMethod. You can override any method this way.
I've never played with overwriting the ShowContextMenu, but I did just make a blog post about how to recursively loop over every form control that sounds like it might help you.
http://alexondax.blogspot.com/2014/05/how-to-use-recursion-to-loop-over-form.html
I'd imagine you could create some sort of handler and key/value thing if you're creative.

GWT CellList... when item clicked, previously clicked item loses its style

I have GWT CellList and after adding items via a DataProvider I use the following code to add styling to each item.
members... we can styling if a matched item is also in members
matched... passed in as a MetaJsArray<Contact>
CellList<Contact> list = getView().getResults();
for (int i=0; i<matched.length(); i++) {
if (members.isExistingEntry(matched.get(i))) {
list.getRowElement(i).addClassName("RED");
}
}
This code works until... I click items in the list.
onCellPreview() is called for each item clicked, but the previously clicked item loses its "RED" styling.
Do I need to add styling differently? Or how do I stop the loss of "RED"?
My guess its something to do the way GWT generates the javascript. When you manually set the cell on load its all good. When you select it, the javascript changes the object to use the selected CSS and when you un select it, the CSS changes to the default GWT CSS style for the cell.
Only way I can think of is to have a handler on select. When you select an item:
selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
public void onSelectionChange(SelectionChangeEvent event) {
// get item last selected
// check if needs re styling
// restyle
// do things with the new selected object
}
});
Add another check through the cell list and mark the ones that got unmarked.
This way might be inefficient, but its one way of avoiding your problem that I can think of. hope it helps.
After trying various approaches the only want that works, without hacks, is to define the style at the point of rendering.
With my own ContactCell extending AbstractCell the render() function can pass in a styling value into the contactcell.ui.xml file.
#Override
public void render(Context context, Contact value, SafeHtmlBuilder sb) {
if (value == null) {
return;
}
String styling = value.getStyling();
uiRenderer.render(sb, styling);
}
and then in contactcell.ui.xml file
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>
<ui:with field='styling' type='java.lang.String'/>
<div class="{styling}"> ... </div>
GWT will mangle the style name so define your own CssResource class to access the class name thru so that the class name is mangled throughout the app.

CommitProperties in a custom component doesn't work with percent width

My problem is pretty much described in the title. Just a few details .. I'm creating a custom component (based on ComboBox) and overriding some base methods. Recently I've found it acts weird when I set it's width in percents, rather than a fixed width. It tends to continuously call the commitProperties method and fail in the end. When I set it's width to fixed value - all works like a charm. What am I missing to implement? Here's some code ..
override protected function commitProperties():void {
super.commitProperties();
//some stuff ...
TextInput(textInput).setSelection(cursorPosition, cursorPosition);
if (cursorPosition == textInput.text.length || cursorPosition == 0) {
TextInput(textInput).horizontalScrollPosition = (cursorPosition == 0) ? 0 : textInput.width;
}
}
Here, the textInput.width properly returning a calculated value, in both cases.
And, just for a case, if it's needed:
override protected function measure():void {
super.measure();
measuredWidth = 160;
}
I'm not sure if something else is needed .. just ask if so.
Thanks in advance :)
The issue is not obvious but it is generally a good practise to call super.commitProperties(); at the end of overridden commitProperties() implementation rather than at the beginning.
If your //some stuff... block invalidates properties it won't be handled correctly if you called super.commitProperties(); on the first line.
Unfortunately it's not possible to debug this kind of issue without a full code...
If you are extending Flex 3 MX ComboBox have a look at ComboBase.updateDisplayList() to understand when / how textInput is sized.
The textInput.width is updated in ComboBase.updateDisplayList() so you shouldn't rely on this value during commitProperties(). You can try moving your scroll position logic to the end of updateDisplayList() of your component (at this point width should be updated).
Good luck!

How do I change the appearance of nodes in a Tree control in Flex using an extended TreeItemRenderer?

I'm using a tree control that I want to customize. The data items in the tree's dataProvider have a property name that should be used for labeling the node, and a property type that should be used to select one of several embedded images for use as an icon. The simplest way to do this is by using the labelField and iconFunction properties.
However, I wanted to get started with item renderers and open the door for adding more complex customization later, so I tried making my own item renderer. I extended the TreeItemRenderer class as follows and used it in my tree control:
class DirectoryItemRenderer extends TreeItemRenderer
{
[Embed("assets/directory/DefaultIcon.png")]
private static var _DEFAULT_ICON:Class;
// ... some more icons ...
override public function set data(value:Object):void
{
super.data = value; // let the base class take care of everything I didn't think of
if (value is Node) { // only handle the data if it's our own node class
switch ((value as Node).type) {
// ... some case clauses ...
default:
this._vSetIcon(_DEFAULT_ICON);
}
this.label.text = (value as Node).name;
}
}
private function _vSetIcon(icon:Class):void
{
if (null != this.icon && this.contains(this.icon)) {
this.removeChild(this.icon);
}
this.icon = new icon();
this.addChild(this.icon);
this.invalidateDisplayList();
}
}
This code has no effect whatsoever, icon and label in the tree control remain at their defaults. Using trace(), I verified that my code is actually executed. What did I do wrong?
Looking at the base mx.controls.treeClasses.TreeItemRenderer class, I see that in the updateDisplayList function the renderer gets it's icon and disclosureIcon classes from _listData:TeeListData. Instead of overriding the updateDisplayList function, try modifying the icon and disclosureIcon classes of the renderer's private _listData instance in your _vSetIcon method using the public accessors, like so:
private function _vSetIcon(icon:Class, disclosureIcon:Class = null):void
{
var tmpListData:TreeListData;
if (disclosureIcon == null) disclosureIcon = icon;
tmpListData = this.listData;
tmpListData.icon = icon;
tmpListData.disclosureIcon = disclosureIcon;
this.listData = tmpListData;
}
EDIT
Here is some clarification on the difference between data and listData. You'll have to excuse my omission of package names but I'm editing from my phone so its tough to look them up and I don't know the package names off the top of my head. data is defined in the context of a TreeItemRenderer in the IDataRenderer interface. You create a data renderer by implementing this interface and defining a public property data, which in this case is set by the parent control and contains some data and meta-data from the dataProvider to be rendered by the data renderer class.
listData is defined in the IDropInListItemRenderer interface as a property of type BaseListData and is realized in the TreeItemRenderer class as a property TreeListData. It differs from the data property in that it contains meta-data that describes the TreeListRenderer itself (icon, indent, open) as well as (I believe, I'll have to double check this later) a reference to the data item being rendered. I gather that It's used by the the TreeItemRenderer and I would imagine the parent list control for display update and sizing purposes. Someone is free to correct or add onto that if I'm incorrect or missed something, I'm going of what I remember drom the code.
In this case, you wanted to use meta-data from the data set from the data provider to modify data that determines the display of the renderer, so you would need to modify both.
I think the real confusion here however came from the fact that you extended the TreeItemRenderer class then tried to override functionality on the component in a manner the original developer didn't intend for someone to do, hence the unexpected results. If your goal is education and not ease of implementation you would probably be better served by extending the UIComponent class and using the TreeItemRenderer code as a reference to create a class that implements the same interfaces. That would be a real dive into the pool of custom component development.
I'd probably try something simple, as in this example from the Adobe Cookbooks. I notice that they override updateDisplayList, which may have something to do with your problems.
There's another example (for Flex 2, but looks applicable to Flex 3) that shows how to manage the default icons. It looks like you'll want to manage the icon yourself, setting the default icon styles to null, instead of trying to manipulate the superclass's icon property.
Update -- Looking at the source for TreeItemRenderer, commitProperties has the following before checking the data and setting up the icon and label:
if (icon)
{
removeChild(DisplayObject(icon));
icon = null;
}
Also, it looks like the setter for data calls invalidateProperties. Hence, your icon is wiped out when the framework gets around to calling commitProperties.

Resources