How to get Clicked widgets on gwt VerticalPanel? - gwt

I want to know urgently how to get widget from gwt VerticalPanel that was occured clickEvent.
I have a verticalPanel with on or more sub-Widgets (FlexTables). I want to use FlexTable.getCellForEvent(event).getRowIndex(); method. So , firstly I should get FlexTable widget from VerticalPanel firstly. I want to add addClickHandler or DomHandler on this VerticalPanel and when user click on it , I want to retrieve FlexTable widget that userclicked. But I don't want to iterate on verticalPanel and add ClickHandler on each FlexTable widgets. How to develop them ? Any Suggestions would be appreciated. Thanks in advance for careful of my question..

You can get it by ClickEvent event
public void onClick(final ClickEvent event) {
VerticalPanel vp = (VerticalPanel) event.getSource();
Iterator<Widget> vp = verP.iterator();
while (vPanelWidgets.hasNext()){
Widget childWidget = vPanelWidgets.next();
if (childWidget instanceof FlexTable) {
...do stuff with childWidget
}
}
}

Really my page show list of FlexTables embedded in VerticalPanel. These flexTables were inserted dynamically and there has checkbox in first columns. My trouble is , when users click on any tables and I want to set checkbox in that row to select. When the users click again in it , the checkbox in that row will unchecked. Here my codes.....
view.getResultPanel().addDomHandler(new ClickHandler() {
public void onClick(final ClickEvent event) {
VerticalPanel vpanel = (VerticalPanel) event.getSource();
for (int i = 0; i < vpanel.getWidgetCount(); i++) {
Widget childWidget = vpanel.getWidget(i);
if (childWidget instanceof FlexTable) {
FlexTable table = (FlexTable) childWidget;
if (table.getCellForEvent(event) != null) { // that will avoid invalid table (that not clicked )
int currentRowIndex = table.getCellForEvent(event).getRowIndex();
Element elem = table.getCellFormatter().getElement(currentRowIndex, 0);
if ("td".equalsIgnoreCase(elem.getTagName())) {
elem = elem.getFirstChildElement();
}
if ("center".equalsIgnoreCase(elem.getTagName())) {
elem = elem.getFirstChildElement();
}
boolean isChecked = false;
if ("".equalsIgnoreCase(elem.getAttribute("checked"))) {
elem.setAttribute("checked", "on");
isChecked = true;
}
else if ("on".equalsIgnoreCase(elem.getAttribute("checked"))) {
elem.removeAttribute("checked");
}
if (isChecked) {
// Do Something
}
}
}
}
}
}, ClickEvent.getType());
At UI view... I create this checkbox like that ..
flxResultTable.setHTML(0, 0, "<center><input type = 'checkbox'/></center>");

Related

In Gwt Drag and Drop, how to drop a widget into a right position of a VerticalPanel that already has many labels on it?

Ok, let say, you got a label, you got a VerticalPanel that has many labels on it. See this code:
// Make the widget draggable.
Label w = new Label("OutSide Label");
w.getElement().setDraggable(Element.DRAGGABLE_TRUE);
// Add a DragStartHandler.
w.addDragStartHandler(new DragStartHandler() {
#Override
public void onDragStart(DragStartEvent event) {
// Required: set data for the event.
event.setData("text", "Hello World");
// Optional: show a copy of the widget under cursor.
event.getDataTransfer().setDragImage(w.getElement(), 10, 10);
}
});
VerticalPanel vp=nw VerticalPanel();
vp.add(new Label("l1");
vp.add(new Label("l2");
vp.add(new Label("l3");
vp.addDomHandler(new DragOverHandler() {
public void onDragOver(DragOverEvent event) {
vp.getElement().getStyle().setBackgroundColor("#ffa");
}
}, com.google.gwt.event.dom.client.DragOverEvent.getType());
vp.addDomHandler(new DropHandler() {
#Override
public void onDrop(com.google.gwt.event.dom.client.DropEvent event) {
// TODO Auto-generated method stub
event.preventDefault();
// Get the data out of the event.
String data = event.getData("text");
//Window.alert(data);
/// WE NEED TO FILL IN THE MISSING CODE HERE
/// WE NEED TO FILL IN THE MISSING CODE HERE
}
}, DropEvent.getType());
how to code so that when user drag the outside label into the area of VerticalPanel, if the outside label was dragged between the existing widgets, it will be inserted into the between of existing labels on VerticalPanel, Ex if the outside label was drag between "l1" & "l2", the vp will show:
l1
OutSide Label
l2
l3
Something like the following should theoretically work, although not tested:
p.addDomHandler(new DropHandler() {
#Override
public void onDrop(DropEvent event) {
// Get the target event.
EventTarget eventTarget = event.getNativeEvent().getEventTarget();
// Safe check for casting to Element.
if (Element.is(eventTarget)) {
Element elementTarget = Element.as(eventTarget);
// Loop through VerticalPanel's children to find our target.
for (int i = 0; i < p.getWidgetCount(); ++i) {
if (p.getWidget(i).getElement().isOrHasChild(elementTarget)) {
// Insert a new Label with the DataTransfer's data,
// and remove the old one.
p.insert(new Label(event.getData("text")), i);
oldLabelContainer.remove(oldLabel);
break;
}
}
}
}
}, DropEvent.getType());
Of course, if you have a lot of labels that loop should be avoided.

GWT - Finding which button is checked in a Dynamically generated list of Radiobuttons

I have a for loop that displays a list of text fields and radio buttons.
What is the best way to reference the widgets so that I can read the text fields and aslo find which radio button is checked.
Here is my loop
for(int x = 0; x<getLoopCount(); x++)
{
answerTable.setWidget(x,0, new Label("Answer:"));
answerTable.setWidget(x,1, new TextBox());
answerTable.setWidget(x,2, new RadioButton(""));
}
Is there a way to ID each widget so I can reference it?
I would recommend grouping the three widgets together in a composite widget like this:
class AnswerComposite extends Composite {
private final Label label;
private final TextBox textBox;
private final RadioButton radioButton;
public AnswerComposite() {
label = new Label("Answer:");
textBox = new TextBox();
radioButton = new RadioButton("answerGroup");
HorizontalPanel contentPanel = new HorizontalPanel();
contentPanel.add(label);
contentPanel.add(textBox);
contentPanel.add(radioButton);
initWidget(contentPanel);
}
public String getText() {
return textBox.getValue();
}
public boolean isSelected() {
return radioButton.getValue();
}
}
You can then add them to a panel and/or put them in a list like this:
VerticalPanel answersPanel = new VerticalPanel();
List<AnswerComposite> answerComposites = new ArrayList<AnswerComposite>();
for (int i = 0; i < getLoopCount(); i++) {
AnswerComposite answerComposite = new AnswerComposite();
answersPanel.add(answerComposite);
answerComposites.add(answersComposite);
}
Checking your widgets then becomes very easy:
answerComposites.get(i).getText();
answerComposites.get(i).isSelected();
It will probably also be convenient to add a ValueChangeHandler to your RadioButtons (see enrybo's answer).
You can add a ValueChangeHandler to your RadioButton when you are creating them.
for(int x = 0; x<getLoopCount(); x++){
answerTable.setWidget(x,0, new Label("Answer:"));
answerTable.setWidget(x,1, new TextBox());
RadioButton rb = new RadioButton("");
rb.addValueChangeHandler(new ValueChangeHandler(){
#Override
void onValueChange(ValueChangeEvent<Boolean> event){
// Do something
}
});
answerTable.setWidget(x,2, rb);
}
The ValueChangeEvent will only be fired when the RadioButton is checked. It will not fire if another RadioButton in the same group is checked.
Since you're adding the ValueChangeHandler as you're creating your RadioButton you should know what is to be done with it without having to create an ID for it.
Let me give you an adhoc answer, so don't care about the syntax but the algorithmic idea.
Extend GWT button.
abstract class MyButton
extends Button{
// provide the appropriate constructor in impl class,
// especially if using uibinder
abstract public void helloDolly(... args ...);
}
Instantiate all those buttons using MyButton.
MyButton[] buttons = {
new MyButton(){
public void helloDolly(... args ...){
Window.alert("allo allo #1");
}
},
new MyButton(){
public void helloDolly(... args ...){
Window.alert("allo allo #2");
}
},
// blah blah black sheep ....
}
Use clickEvent.getSource() when defining handler.
buttons[i].addEventHandler(
new ClickHandler(ClickEvent click){
Object src = click.getSource();
if (src !instanceOf MyButton){
throw new MyAngryException("For goodness' sake, pls use MyButton");
// or ignore
return;
}
((MyButton)src).helloDolly(... args ...);
}
)

GWT CellTable Custom Selection Model

I need a 'custom selection model' for GWT CellTable. One of the columns in CellTable is a Checkbox column.
Basic rquirements (both work in solution below):
- Row click (not on checkbox), selects that row and un-selects all other rows.
- Checkbox selection should select/un-select that row only.
Following is the code I am using, but its very very slow. Any guidance would be appreciated.
final SelectionModel<T> selectionModel = new MultiSelectionModel<T>();
dataTable.setSelectionModel(selectionModel,
DefaultSelectionEventManager.createCustomManager(
new DefaultSelectionEventManager.CheckboxEventTranslator<T>() {
#Override
public SelectAction translateSelectionEvent(CellPreviewEvent<T> event) {
SelectAction action = super.translateSelectionEvent(event);
if (action.equals(SelectAction.IGNORE)) {
selectionModel.clear();
return SelectAction.TOGGLE;
}
return action;
}
}
)
);
Following is the code snipped for CheckColumn callback.
Column<T, Boolean> checkColumn = new Column<T, Boolean>(
new CheckboxCell(true, false))
{
#Override
public Boolean getValue(T t)
{
// Get the value from the selection model.
return selectionModel.isSelected(t);
}
};
I have put in a KeyProvider for the CellTable and its not slow anymore. :)
ProvidesKey<T> keyProvider = new ProvidesKey<T>() {
public Object getKey(T t) {
return tip == null? null : tip.getId();
}
};
dataTable = new CellTable<T>(PAGE_SIZE, keyProvider);
You could just whitelist your checkbox
int checkboxColumn = 0;
DefaultSelectionEventManager.createCustomManager(new DefaultSelectionEventManager
.WhitelistEventTranslator(checkboxColumn));

GWT Tab panel close

I am building an application in GWT. I have a decorated tabpanel in
my application.Where in am adding panels to it dynamically.Now i want
to achieve the closing of these tabs. I want to add a close image to
the tab bar and event to that image for closing. I am using UIbinder.
the working code is like that;
private Widget getTabTitle(final Widget widget, final String title) {
final HorizontalPanel hPanel = new HorizontalPanel();
final Label label = new Label(title);
DOM.setStyleAttribute(label.getElement(), "whiteSpace", "nowrap");
ImageAnchor closeBtn = new ImageAnchor();
closeBtn.setResource(images.cross());
closeBtn.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
int widgetIndex = tabs.getWidgetIndex(widget);
if (widgetIndex == tabs.getSelectedIndex()) {
tabs.selectTab(widgetIndex - 1);
}
tabs.remove(widgetIndex);
}
});
hPanel.add(label);
hPanel.add(new HTML("&nbsp&nbsp&nbsp"));
hPanel.add(closeBtn);
hPanel.setStyleName("gwt-TabLayoutPanelTab");
return hPanel;
}
In order to add tab,
public void addTab() {
TabWriting tw = new TabWriting(); /* TabWriting in my case, this can be any widget */
tabs.add(tw, getTabTitle(tw, "Writing"));
tabs.selectTab(tw);
}
You'll going to need, ImageAnchorClass
public class ImageAnchor extends Anchor {
public ImageAnchor() {
}
public void setResource(ImageResource imageResource) {
Image img = new Image(imageResource);
img.setStyleName("navbarimg");
DOM.insertBefore(getElement(), img.getElement(), DOM
.getFirstChild(getElement()));
}}
It isn't supported natively in GWT.
You can manually try to add it.
Read this - http://groups.google.com/group/google-web-toolkit/browse_thread/thread/006bc886c1ccf5e1?pli=1
I haven't tried it personally, but look at the solution by gregor (last one).
You kinda need to do something along the lines of this
GWT Close button in title bar of DialogBox
First you need to pass in the tab header when you create the new tab. The header you pass in should have your tab text and also an X image or text label to click on. Then add a event handler on the close object that gets the widget you are adding to the tabPanel and removes it. Here is some inline code that works
public void loadTab(final Widget widget, String headingText, String tooltip) {
HorizontalPanel panel = new HorizontalPanel();
panel.setStyleName("tabHeader");
panel.setTitle(tooltip);
Label text = new Label();
text.setText(headingText);
text.setStyleDependentName("text", true);
Label close = new Label();
close.setText("X");
close.setTitle(closeText_ + headingText);
text.setStyleDependentName("close", true);
close.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
Window.alert("close this tab");
ClientGlobal.LOG.info("widget : " + tabPanel_.getWidgetIndex(widget));
tabPanel_.remove(tabPanel_.getWidgetIndex(widget));
}
});
panel.add(text);
panel.add(close);
panel.setCellHorizontalAlignment(text, HasHorizontalAlignment.ALIGN_LEFT);
panel.setCellHorizontalAlignment(close, HasHorizontalAlignment.ALIGN_RIGHT);
tabPanel_.add(widget, panel);
tabPanel_.getTabWidget(widget).setTitle(tooltip);
tabPanel_.selectTab(widget);
}

GWT FlexTable - drag selection how?

I am trying to get a proper method for days to select multiple cells in a flextable's column.
So far i only managed to do it with clicks which works well, but a drag selection would be much better. I have been reading docs and searching, but all the stuff i found was based on deprecated code. I use GWT 2.0 .
I know i need some event handler which would run when drag selection mouse gesture occurs, and that handler needs to know the cell's index where the selection start and of course the cell's index where the selection ends.
Any advice || code would be much appreciated.
This needs to be improved but it should give you the basic idea. First you need to create a CustomTable that listens to MouseEvents. You can do this by extending composite to wrap a focuspanel and a flextable as such :
public class CustomTable extends Composite implements MouseDownHandler, MouseMoveHandler, MouseUpHandler{
List<CellWidget> widgets = new ArrayList<CellWidget>();
FlexTable table = new FlexTable();
FocusPanel focusPanel = new FocusPanel();
boolean selecting= false;
Point selectStart,selectEnd;
public CustomTable(){
focusPanel.setWidget(table);
focusPanel.addMouseDownHandler(this);
focusPanel.addMouseMoveHandler(this);
focusPanel.addMouseUpHandler(this);
initWidget(focusPanel);
}
public void setWidget(int row, int column, CellWidget widget){
widgets.add(widget);
table.setWidget(row, column, widget);
}
#Override
public void onMouseUp(MouseUpEvent event) {
event.preventDefault();
if (selecting){
selecting=false;
DOM.releaseCapture(this.getElement());
selectEnd = new Point(event.getClientX(),event.getClientY());
for (CellWidget widget : widgets){
if (widget.isIn(selectStart,selectEnd))
widget.say();
}
selectStart = selectEnd = null;
}
}
#Override
public void onMouseMove(MouseMoveEvent event) {
event.preventDefault();
if (selecting){
//do some fancy layout
}
}
#Override
public void onMouseDown(MouseDownEvent event) {
event.preventDefault();
selecting = true;
DOM.setCapture(this.getElement());
selectStart = new Point(event.getClientX(),event.getClientY());
}
}
Next you define a CellWidget which basically encapsulates what you would like to add to your cells. When added to DOM, CellWidget calculates and stores its position later to determine if it is in the selected area :
public class CellWidget extends Composite{
Widget content;
Point topLeft,topRight,bottomLeft,bottomRight;
public CellWidget(Widget w){
this.content = w;
initWidget(w);
}
#Override
protected void onLoad() {
topLeft = new Point(getAbsoluteLeft(),getAbsoluteTop());
topRight = new Point(getAbsoluteLeft()+getOffsetWidth(),getAbsoluteTop());
bottomLeft = new Point(getAbsoluteLeft(),getAbsoluteTop()+getOffsetHeight());
bottomRight = new Point(getAbsoluteLeft()+getOffsetWidth(),getAbsoluteTop()+getOffsetHeight());
}
public void say(){
Window.alert(content + " is selected!");
}
public boolean isIn(Point start, Point end){
if (topLeft.isBetween(start, end) || topRight.isBetween(start, end)
|| bottomLeft.isBetween(start, end) || bottomRight.isBetween(start, end))
return true;
else
return false;
}
}
A simple point implementation to make things easier :
public class Point {
int x,y;
public Point(int x,int y){
this.x=x;
this.y=y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
#Override
public String toString() {
return x+","+y;
}
public boolean isBetween(Point p1,Point p2){
if (p1.getX() < x && p2.getX() > x && p1.getY() < y && p2.getY() > y)
return true;
return false;
}
}
Finally at your EntryPoint module you wrap things up by :
public void onModuleLoad() {
RootPanel rootPanel = RootPanel.get();
CustomTable table = new CustomTable();
table.setWidget(0, 0, new CellWidget(new Label("hello 0,0")));
table.setWidget(0, 1, new CellWidget(new Label("hello 0,1")));
table.setWidget(1, 0, new CellWidget(new Label("hello 1,0")));
table.setWidget(1, 1, new CellWidget(new Label("hello 1,1")));
rootPanel.add(table);
}
I know that the actual logic to determine if the widgets fall within the selected area is incomplete and needs to be improved but i think this solution is clear enough to give the basic idea. Cheers