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

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 ...);
}
)

Related

how to access the components of a composite outside its defined method

I have a method called creatcomponents() where I am creating few text fields and buttons in a composite. Now I want to write listeners to the button which calls a method and in this method I have get the values of the text fields. The problem I am facing is I am unable to access textfields from the method called in the listeners. Can someone help me on how to acheive this?
One way is to save the controls are fields in your class:
public class MyClass
{
private Text text1;
private Text text2;
public void createComponents(Composite parent)
{
Composite composite = new Composite(parent, SWT.None);
text1 = new Text(composite, SWT.SINGLE);
text2 = new Text(composite, SWT.SINGLE);
text1.addModifyListener(new ModifyListener()
{
#Override
public void modifyText(ModifyEvent event)
{
// Access field
String text = text1.getText();
}
});
}
}
Also note that many of the event classes passed to listeners have a widget field which refers to the current control which you can also use:
text1.addModifyListener(new ModifyListener()
{
#Override
public void modifyText(ModifyEvent event)
{
Text control = (Text)event.widget;
String text = control.getText();
}
});

How to get Clicked widgets on gwt VerticalPanel?

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>");

GWT:how to get selected radio button's value

I am create dynamic number of radio buttons in my GWT
public void createTestList(ArrayList<Test> result){
for(int i =0 ; i<result.size();i++){
int id = result.get(i).getTestId();
RadioButton rd = new RadioButton("group", result.get(i).getTestType());
verticalPanel.add(rd);
}
where Test is my Entity class ..
I am getting 4 different types of radio buttons in my view , Now if i select any one of the radio button, first I need to get the id of the selected Radio button , how can this be possible ?
secondly How will i check that which one of the multiple radio button is selected ?
Thanks
You need to check public java.lang.Boolean getValue() on each radio button whether it is checked or not.
it is possible to add click handler and update selected radio button variable:
choiceItemKind = new VerticalPanel();
ArrayList<String> kinds = new ArrayList<String>();
kinds.add(...);
kinds.add(...);
choiceItemKind.clear();
ClickHandler choiceClickHandler = new ClickHandler()
{
#Override
public void onClick(ClickEvent event)
{
addItemKindSelectedLabel = ((RadioButton) event.getSource()).getText();
}
};
for (String label : kinds)
{
RadioButton radioButton = new RadioButton("kind", label);
//radioButton.setTitle("Tooltyp");
if (label.equals(addItemKindSelectedLabel))
radioButton.setValue(true);
radioButton.addClickHandler(choiceClickHandler);
choiceItemKind.add(radioButton);
}
...
addItemKindSelectedLabel = "";
...
if (!addItemKindSelectedLabel.isEmpty())
...;
upd: set selected radiobutton without rebuild:
for (int i = 0; i < choiceItemKind.getWidgetCount(); i++)
{
RadioButton radioButton = (RadioButton) choiceItemKind.getWidget(i);
radioButton.setValue(radioButton.getText().equals(addItemKindSelectedLabel));
}

How to programmatically open a gwt listbox?

I have a user form with a lot of gwt listbox. The form is like an excel form with named list.
It's ugly and the arrows take place.
I would like the cells were like in excel. The arrow appears only when you click in the cell.
I start to program my own widget with a textbox and a listbox embedded into a DeckPanel, switching when you click on the textbox or when the value change. But with this solution, it is necessary to click again to open the listbox.
Now, it will be great, if when you click on the textbox, the listbox will be displayed already open.
In the code below, I try to do this into the method onClick wih this line:
DomEvent.fireNativeEvent(event.getNativeEvent(), listBox);
But it has no effects.
public class CustomListBox extends Composite implements ClickHandler,
ChangeHandler, HasChangeHandlers {
private final StringListBox listBox;
private final TextBox textBox;
private final DeckPanel panel;
public CustomListBox() {
textBox = new TextBox();
textBox.addClickHandler(this);
textBox.setReadOnly(true);
listBox = new StringListBox();
listBox.addChangeHandler(this);
panel = new DeckPanel();
panel.add(textBox);
panel.add(listBox);
panel.showWidget(0);
// All composites must call initWidget() in their constructors.
initWidget(panel);
}
#Override
public void onClick(ClickEvent event) {
Object sender = event.getSource();
if (sender == textBox) {
panel.showWidget(1);
DomEvent.fireNativeEvent(event.getNativeEvent(), listBox);
}
}
public void addItem(String item) {
listBox.addItem(item);
}
public int getSelectedIndex() {
return listBox.getSelectedIndex();
}
public String getItemText(int selectedIndex) {
return listBox.getItemText(selectedIndex);
}
#Override
public HandlerRegistration addChangeHandler(ChangeHandler handler) {
return listBox.addChangeHandler(handler);
}
#Override
public void onChange(ChangeEvent event) {
Object sender = event.getSource();
if (sender == listBox) {
textBox.setText(getItemText(getSelectedIndex()));
panel.showWidget(0);
}
}
}
Since you are already programming your own widget, why don't you go all the way. Don't swap out the text box for a list box widget. Instead of a textbox use a label. Add an arrow to your label background when you mouse over, then use a popupPanel for the list itself. In the popupPanel you can make the list items whatever you like, just make sure when you click on it, it sets the text in your original label.

GWT CellList; programmatical scrolling between elements options

I would like to understand the options available to scrolling to a specific element in a CellList? Currently I have a 100 elements in the list and need to "jump" through the elements at the click of a button but can't seems to locate any methods on the celllist (or in the code) that provides this feature.
Any Ideas?
Many Thanks in advance,
Ian.
**EDIT
working code example below;
public class CellListTest implements EntryPoint {
private CellList<String> cellList;
private SingleSelectionModel<String> stringSingleSelectionModel;
/**
* This is the entry point method.
*/
public void onModuleLoad() {
cellList = new CellList<String>(new TextCell());
cellList.setRowData(buildStringList(200));
cellList.setKeyboardSelectionPolicy(HasKeyboardSelectionPolicy.KeyboardSelectionPolicy.BOUND_TO_SELECTION);
Button byTen = new Button("Jump Forward 10");
stringSingleSelectionModel = new SingleSelectionModel<String>();
cellList.setSelectionModel(stringSingleSelectionModel);
byTen.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
jumpForward(10);
}
});
byTen.setHeight("30px");
HTMLPanel htmlPanel = new HTMLPanel("");
VerticalPanel verticalPanel = new VerticalPanel();
cellList.setHeight("600px");
ScrollPanel scrollPanel = new ScrollPanel(cellList);
verticalPanel.add(byTen);
verticalPanel.add(scrollPanel);
htmlPanel.add(verticalPanel);
RootLayoutPanel.get().add(htmlPanel);
}
final Random random = new Random();
private List<String> buildStringList(int numberToCreate) {
final ArrayList<String> randomValues = new ArrayList<String>();
for (int i = 0; i < numberToCreate; i++) {
randomValues.add(String.valueOf(random.nextInt()));
}
return randomValues;
}
private int currentPosition = 0;
private void jumpForward(int toJump) {
Element rowElement = cellList.getRowElement(currentPosition += toJump);
rowElement.scrollIntoView();
}
}
I do not think CellList has a direct method for your purpose.
What you can do is use Element's scrollIntoView method. This method adjusts the scrollLeft and scrollTop properties of each scrollable element to ensure that the specified element is completely in view. In order to use that method you need to get the element containing the cell you want to show. One way to achive this is by using CellList public getRowElement(int indexOnPage).
I have not tryed it, but I believe the following code should work:
//Ensures cell 22 on page is shown
Element element = myCellList.getRowElement(22);
element.scrollIntoView();
Scrolling the element into view is one thing; changing the keyboard focus to a particular element is quite another. After much exploration, I have found that the best way to achieve that is to fire native events to simulate the user pressing keys.
private void hitKeyOnList(int keyCode) {
NativeEvent keyDownEvent = Document.get().createKeyDownEvent(
false, false, false, false, keyCode);
list.getElement().dispatchEvent(keyDownEvent);
}
In the above snippet, the list variable is a reference to a CellList.
So, to move the cursor to the end of the list, do this:
hitKeyOnList(KeyCodes.KEY_END);
to move the cursor to the next item down from the one that currently has keyboard focus:
hitKeyOnList(KeyCodes.KEY_DOWN);
This approach should work for all of these keys, which are handled by AbstractHasData:
KeyCodes.KEY_DOWN
KeyCodes.KEY_UP
KeyCodes.KEY_PAGEDOWN
KeyCodes.KEY_PAGEUP
KeyCodes.KEY_HOME
KeyCodes.KEY_END