how to access an widget attached to a treeitem in GWT - gwt

I'm using GWT TreeItem Widget in my program. I add the checkboxes in to the treeitems dynamically. The code is given below. Please note these items starting with "ti" are TreeItems which were defined earlier in this code..
private void polulateTree(List<String> single, List<String> multi,
List<String> sub, List<String> local) {
for (String fm:single) {
this.tilftSingleV.addItem(new CheckBox(fm));
}
for (String vm:multi) {
this.tilftMultiV.addItem(new CheckBox(vm));
}
for (String sm:sub) {
this.tilftSubV.addItem(new CheckBox(sm));
}
for (String lr:local) {
this.tilftLocalR.addItem(new CheckBox(lr));
}
}
Now I want to access these checkboxes. I don't find a method within TreeItem widget which returns the Widget attached to a certain index. I'm looking for something like below, which I don't find.
CheckBox chksingle = (CheckBox)tilftSingleV.getWidget(int index)
Any help would be appreciated.

From the gwt documentation:
http://www.gwtproject.org/javadoc/latest/com/google/gwt/user/client/ui/TreeItem.html
getChild(int index): Gets the child at the specified index.
getWidget(): Gets the Widget associated with this tree item.
Widget w = tilftSingleV.getChild(index).getWidget();
if(w instanceof CheckBox)
//Do something with the CheckBox

Related

Storing seekbar values after drag drop process end in ListView

I have listView with drag drop functionality. I'm using ListView with custom layout- I have SeekBar and TextView in custom ListView layout. When I drag and drop each ListView items after changing SeekBar value, TextView is moving and SeekBar value is not moving.
It may be caused by Adapter. So I've share my adapter codes.
https://gist.github.com/salihyalcin/38e320726e3ab8346c50
Thanks in advance
EDIT --- My ListItem Class
class ListItem {
String textdata;
public ListItem(String textdata) {
this.textdata = textdata;
}
public boolean equals(Object o) {
ListItem ndListItemObject = (ListItem) o;
return this.textdata.equalsIgnoreCase(ndListItemObject.textdata);
}
}
** My ListView looks like image below
** Change the SeekBar value of Layer1
** Drag-Drop Layer1 and Layer2
** Layer1 and Layer2 moved but SeekBar values stay same place, they didn't moved.
I think I have an idea. First, your post is missing code snippet of the definition of NavigationDrawerFragment.ListItem class, could be helpful. I do remember that you call method swapElements in DynamicListView but other readers probably don't need to know it.
My suggestion is to save the progress value into the ListItem class, sample code below. We will depend on swapElements() to swap the 2 ListItem objects properly, along with the progress and text (layers in your case).
EDIT, code suggestion for ListItem class:
class ListItem {
String textdata;
int seekBarValue;
public ListItem(String textdata) {
this.textdata = textdata;
}
public ListItem(String textdata, int seekBarValue) {
this.textdata = textdata;
this.seekBarValue = seekBarValue;
}
...
Notes for ListItem code:
Added seekBarValue as a public data member, and another ListItem constructor for the caller's convenience.
This is what I meant by add another data member to this class.
Code snippet suggestion for the Adapter:
holder.mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
final NavigationDrawerFragment.ListItem item = myItems.get(position);
View view = (View) seekBar.getParent();
if (view != null) {
holder.text.setText(progress + "%");
item.seekBarValue = progress;
Notes:
Added code line ...item = myItems.get(position); to get the correct item in the ArrayList.
Set the progress to item.seekBarValue
You may remove these codes below unless you plan on using it, of course:
holder.mSeekBar.getTag();
holder.text.getTag();
mar.get(1,progress);

Disable/mask TabItem's content panel in ExtGwt

I have a TabPanel with two TabItems in ExtGwt. I want to make both the TabItem selectable/clickable but want to disable/read-only the content panel in the TabItem so that user can not perform any action like input text in the textbox or select any field etc. I tried various approaches but it didnot worked for me. I don't want to make the whole tab disable.
This answer may be useful: https://stackoverflow.com/a/2063082/1313968
An alternative approach is to disable all components in the panel, for example just pass your ContentPanel to the following method:
private void containerSetEnabled(final Container container, final boolean enabled) {
for (int widgetIndex = 0; widgetIndex < container.getWidgetCount(); ++widgetIndex) {
final Widget widget = container.getWidget(widgetIndex);
if (widget instanceof Container) {
containerSetEnabled((Container)widget, enabled);
}
else if (widget instanceof Component) {
((Component)widget).setEnabled(false);
}
}
}

Adding button to SimplePanel results in error

I am performing the following action in GWT
public class FooPanel extends SimplePanel {
private String url;
public FooPanel () {
super(DOM.createAnchor());
Button button = new Button();
button.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
foo();
}
});
add(button);
}
}
however when I run the code I get the following error
SimplePanel can only contain one child widget
However Button is a single widget so I am not sure what the problem is? The problem doesn't occur if i don't add the button
Remove this line:
super(DOM.createAnchor());
You don't need it.
You can simply use your Button in your code, or extend a Button widget. Adding a Button to a SimplePanel does not offer any benefits.
Have a look at source code of SimplePanel#add() to analyze this error.
#Override
public void add(Widget w) {
// Can't add() more than one widget to a SimplePanel.
if (getWidget() != null) {
throw new IllegalStateException("SimplePanel can only contain one child widget");
}
setWidget(w);
}
Now its clear from the source code that you have already added a widget in SimplePanel.
Call SimplePanel#getWidget() to get the already added widget.
Look at the source code of default constructor if SimplePanel class. It might help you to understand that how SimplePanel enclose the widget inside it.
/**
* Creates an empty panel that uses a DIV for its contents.
*/
public SimplePanel() {
this(DOM.createDiv());
}
Try with setWidget(button); instead of add(button);

GWT - How to retrieve real clicked widget?

I have onClick event on somePanel. And I click on it and it works. But.. How to retrieve real click target? When I click on panel which is inside od somePanel it show me that I click on somePanel..
I know we have this:
Element e = Element.as( event.getNativeEvent().getEventTarget());
But i returns element - I want widget..
How to do this?
This is an old question, but both answers are wrong. If you are using a GWT EventListener and want the widget that is the source of the event, then you simply use the event.getSource() method of the event and cast it to the original object type.
Unless there is something that I am missing in the question here.
I would use the feature in gwtquery to get the widget associated with a given element: https://code.google.com/p/gwtquery/wiki/GettingStarted#Manipulating_your_widgets
Widget = $(e).widget();
The problem is that the element clicked couldn't be the element associated with the widget but a child. In this case you could use gquery selectors to traverse the dom until you get its parent widget based on some css property.
// Most gwt widgets contains a class .gwt- but this could fail
// so use a more accurate selector than the one in this example
Widget = $(e).closest("[class*='.gwt-']")
If you wanted to do it by yourself, taking a look to the method getAssociatedWidget in GQuery gives you the solution:
EventListener listener = DOM.getEventListener(e);
// No listener attached to the element, so no widget exist for this element
if (listener == null) {
return null;
}
if (listener instanceof Widget) {
// GWT uses the widget as event listener
return (Widget) listener;
}
EDITED: here you have a working example:
import static com.google.gwt.query.client.GQuery.*;
// A panel with some widgets
Panel panel = new VerticalPanel();
final HTML widget1 = new HTML("<span>Foo</span> <span>Bar</span");
final HTML widget2 = new HTML("<span>Foo</span> <span>Bar</span");
final HTML widget3 = new HTML("<span>Foo</span> <span>Bar</span");
panel.add(widget1);
panel.add(widget2);
panel.add(widget3);
// we need to wrap our panel with a widget supporting click events
FocusPanel wrapper = new FocusPanel();
wrapper.add(panel);
RootPanel.get().add(wrapper);
wrapper.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
// The element is not the HTML widget clicked but the span element
Element e = event.getNativeEvent().getEventTarget().cast();
// Using gquery to get the closest widget to the clicked element
// We take advanrage of HTML widgets having gwt-HTML class
Widget w = $(e).closest(".gwt-HTML").widget();
if (w == widget1) {
Window.alert("Clicked on widget 1");
} else if (w == widget2) {
Window.alert("Clicked on widget 2");
} else if (w == widget3) {
Window.alert("Clicked on widget 3");
} else {
Window.alert("Clicked on a non GWT HTML widget");
}
}
});
An alternative approach, if you already know all of the widgets that you want to check against, would be to use the DOM.isOrHasChild(Element) or Element.isOrHasChild(Node).
For example:
public void onClick(ClickEvent event) {
Element targetElem = Element.as(event.getNativeEvent().getEventTarget());
Widget targetWidget = null;
if (widgetA.getElement().isOrHasChild(targetElem) {
targetWidget = widgetA;
}
else if (widgetB.getElement().isOrHasChild(targetElem) {
targetWidget = widgetA;
}
.....
if (targetWidget != null) {
// You found you widget - Yay!
}
else {
// No widget found - Bummer!
}
}
This approach only works if you know the widgets you are testing against up front. The benefit is that you now have an particular widget reference rather then a generic reference to 'some' widget that you might have to do additional checks against.
For example, you could have done the following if widgetA was a subclass of TextBox called MySpecialTextBox:
MySpecialTextBox widgetA;
if (widgetA.getElement().isOrHasChild(targetElem) {
widgetA.someSpecialMethod();
}

Adding links to a row in a column on click (CellTable)

I have a CellTable where I want to add several links to a row when I click an add button. Right now Im facing the problem that when I click the add button the link will be added to all rows in that column. Somehow it feels like I only can add things to columns.
// shows project column
final MultipleLinkTextCell projectCell = new MultipleLinkTextCell();
final Column<Booking, String> projectColumn = new Column<Booking, String>(
projectCell) {
#Override
public String getValue(Booking project) {
return "";
}
};
getView().getTimeTable().addColumn(projectColumn, "Tasks");
An Example with Buttons
#Override
protected void render(com.google.gwt.cell.client.Cell.Context context,
SafeHtml data, SafeHtmlBuilder sb) {
String string = "";
for (int i = 0; i < value; i++) {
string += "<button type=\"button\" style=\" height:20px; width:22px\">";
}
sb.appendHtmlConstant(string);
if (data != null) {
sb.append(data);
}
}
Im thinking about to use the Anchor widget because I can handle the placemanager from gwtp with it. But still I dont know how to add widgets to a specific row.
//Update:
I did it like this now, it works, but its better to use the revealmanager. The hardcoded link is kinda bad because I always need to change the reference to the link when I change the webserver. I get a string with several values splitted by a commar.
#Override
protected void render(com.google.gwt.cell.client.Cell.Context context,
SafeHtml data, SafeHtmlBuilder sb) {
String stringData = data.asString();
String[] splitResult = stringData.split(",");
for (int i = 0; i < splitResult.length; i++) {
if (!splitResult[i].equals("")) {
sb.appendHtmlConstant("<div><a href=\"http://127.0.0.1:8888/gwtpTimeTracking.html?gwt.codesvr=127.0.0.1:9997#project;projectid="+splitResult[i].substring(0, 7)+"\">"
+ splitResult[i].substring(0, 7) + "</a></div>");
}
}
You can't use any Widgets in CellWidgets.
However you can create your custom cell that mimics it or create an ActionCell and add a VaueUpdater that fires a PlaceRequest Event.
For adding the link to a specific row you have to add a field (i..e List<String> links) to your DTO that is rendered in your CellTable. When you click on the "Add" button you have to modify the field of the specific DTO in your list.
MyDTO obj = // get the specific DTO from the DataProvider
obj.setLinks(LIST OF LINKS);
In the render method of your custom cell you check the field (i..e links) and either render out the links or not.
Where does the value data in your render method come from ?