I am trying to add a hyperlink in celltable and on clicking on that link i want to call a method.
with the below code i am getting a hyperlink in my celltable correctly but I am not able to call a method by clicking on the link , when i click the link it takes me to the previous page.
Any Solution
Hyperlink link = new Hyperlink("Delete","");
Column<EmployerJobs, Hyperlink> linkColumn =
new Column<EmployerJobs, Hyperlink>(new HyperLinkCell()) {
#Override
public Hyperlink getValue(EmployerJobs list) {
link.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
deleteJobs(list);
}
});
return link;
}
});
Instead of a HyperlinkCell you can either use a ClickableTextCell, a ButtonCell or an ActionCell.
ClickableTextCell:
Column<EmployerJobs, String> linkColumn =
new Column<EmployerJobs, String>(new ClickableTextCell()) {
#Override
public String getValue(EmployerJobs object) {
return TEXT_TO_DISPLAY;
}
},'linkheadertext');
linkColumn.setFieldUpdater(new FieldUpdater<EmployerJobs, String>() {
#Override
public void update(int index, EmployerJobs object, String value) {
deleteJobs(object);
}
});
ButtonCell:
Column<EmployerJobs, String> buttonColumn =
new Column<EmployerJobs, String>(new ButtonCell()) {
#Override
public String getValue(EmployerJobs object) {
return TEXT_TO_DISPLAY;
}
},'linkheadertext');
buttonColumn.setFieldUpdater(new FieldUpdater<EmployerJobs, String>() {
#Override
public void update(int index, EmployerJobs object, String value) {
deleteJobs(object);
}
});
ActionCell:
Column<EmployerJobs, EmployerJobs> actionColumn =
new Column<EmployerJobs, EmployerJobs>(new ActionCell<EmployerJobs>("Click Me",
new ActionCell.Delegate<EmployerJobs>() {
#Override
public void execute(EmployerJobs jobs) {
deleteJobs(jobs);
}
})
{
#Override
public EmployerJobs getValue(EmployerJobs object) {
return object;
}
},'linkheadertext');
Check out the CellSample showcase for more infos.
I have post my answer on the similar thread:
How can I render a ClickableTextCell as an anchor in a GWT CellTable?
but for those who bookmarked this thread:
This is what you need
public class ClickableSafeHtmlCell extends AbstractCell<SafeHtml> {
/**
* Construct a new ClickableSafeHtmlCell.
*/
public ClickableSafeHtmlCell() {
super("click", "keydown");
}
#Override
public void onBrowserEvent(Context context, Element parent, SafeHtml value, NativeEvent event,
ValueUpdater<SafeHtml> valueUpdater) {
super.onBrowserEvent(context, parent, value, event, valueUpdater);
if ("click".equals(event.getType())) {
onEnterKeyDown(context, parent, value, event, valueUpdater);
}
}
#Override
protected void onEnterKeyDown(Context context, Element parent, SafeHtml value,
NativeEvent event, ValueUpdater<SafeHtml> valueUpdater) {
if (valueUpdater != null) {
valueUpdater.update(value);
}
}
#Override
public void render(Context context, SafeHtml value, SafeHtmlBuilder sb) {
if (value != null) {
sb.append(value);
}
}
And then usage:
Column<YourProxy, SafeHtml> nameColumn = new Column<YourProxy, SafeHtml>(
new ClickableSafeHtmlCell()) {
#Override
public SafeHtml getValue(YourProxy object) {
SafeHtmlBuilder sb = new SafeHtmlBuilder();
sb.appendHtmlConstant("<a>");
sb.appendEscaped(object.getName());
sb.appendHtmlConstant("</a>");
return sb.toSafeHtml();
}
};
nameColumn.setFieldUpdater(new FieldUpdater<YourProxy, SafeHtml>() {
#Override
public void update(int index, YourProxy object, SafeHtml value) {
Window.alert("You have clicked: " + object.getName());
}
});
As suggested in above answer you can use updater when you want inplace editing. But if you want to capture a click to perform some action, you can do it using ClickableTextCell.
ClickableTextCell employerJobsCell = new ClickableTextCell();
Column<EmployerJobs, String> employerJobsColumn = new Column<EmployerJobs, String>(employerJobsCell) {
#Override
public String getValue(EmployerJobs object) {
return object.getWhichStringToDisplay();
}
#Override
public void render(Context context, EmployerJobs object, SafeHtmlBuilder sb) {
//this method is optional, can be used if the display needs to be customized
}
#Override
public void onBrowserEvent(Context context, Element elem, EmployerJobs object, NativeEvent event) {
super.onBrowserEvent(context, elem, object, event);
Event evt = Event.as(event);
int eventType = evt.getTypeInt();
if (eventType == Event.ONCLICK) {
//call delete job when cell is clicked
deleteJobs(object);
}
}
};
dataGrid.addColumn(employerJobsColumn, "The header goes here");
Related
private ArrayList<MFRList> list;
private ArrayList<STUList> list1 = new ArrayList<STUList>();
public ResultPage(PageParameters params) throws APIException {
Form form = new Form("form");
PageableListView view = new PageableListView("view", list, 10) {
#Override
public void onConfigure() {
super.onConfigure();
setVisible(list.size() > 0);
}
#Override
protected void populateItem(ListItem item) {
final StuList stu= (StuList) item.getModelObject();
item.add(new CheckBox("check", item.getModel()));
item.add(new Label("name", stu.getName()));
item.add(new Label("num", stu.getNumber()));
item.add(new Label("age", stu.getAge()));
item.add(new Label("sex", stu.getSex()));
}
};
Button backtosearchbutton = new Button("backtosearchbutton") {
#Override
public void onSubmit() {
setResponsePage(SearchPage.class);
}
}.setDefaultFormProcessing(false);
Button groupcheckbutton = new Button("groupcheckbutton") {
#Override
public void onSubmit() {
}
}.setDefaultFormProcessing(false);
Button groupuncheckbutton = new Button("groupuncheckbutton") {
#Override
public void onSubmit() {
}
}.setDefaultFormProcessing(false);
Button submitselectionbutton = new Button("submitselectionbutton") {
#Override
public void onSubmit() {
}
}.setDefaultFormProcessing(true);
form.add(view);
form.add(backtosearchbutton);
form.add(submitselectionbutton);
form.add(groupuncheckbutton);
form.add(groupcheckbutton);
add(form);
add(new CustomPagingNavigator("navigator", view));
how are the selected records stored and how can i use it. i understand that on form submission these records are submitted but i am not clear on how and where.
and my pojo is
public class MFRList implements Serializable {
private String name;
private String num;
private String age;
private String sex;
private Boolean selected = Boolean.FALSE;
public String getName() {
return Name;
}
public void setName(String Name) {
this.Name = Name;
}
public String getnum() {
return num;
}
public void setnum(String num) {
this.num = num;
}
public String getAge() {
return age;
}
public void setsex(String sex) {
this.sex= sex;
}
public String getsex() {
return sex;
}
public void setage(String age) {
this.age = age;
}
public Boolean getSelected() {
return selected;
}
public void setSelected(Boolean selected) {
this.selected = selected;
}
}
where is the selected row saved and how can i retrieve and use it.
Thanks in Advance
You should use a CheckGroup with Checks instead:
public ResultPage(PageParameters params) throws APIException {
Form form = new Form("form");
CheckGroup selection = new CheckGroup("selection", new ArrayList());
selection.setRenderBodyOnly(false);
form.add(selection);
PageableListView view = new PageableListView("view", list, 10) {
#Override
public void onConfigure() {
super.onConfigure();
setVisible(list.size() > 0);
}
#Override
protected void populateItem(ListItem item) {
final StuList stu= (StuList) item.getModelObject();
item.add(new Check("check", item.getModel()));
item.add(new Label("name", stu.getName()));
item.add(new Label("num", stu.getNumber()));
item.add(new Label("age", stu.getAge()));
item.add(new Label("sex", stu.getSex()));
}
};
selection.add(view);
This way the arrayList passed to the CheckGroup constructor will always contain the selected objects.
I got what i was trying to acheive but i am not su7re if it is optimal solution.
I created my own Model and added the object to a list when check box is selected.
class SelectedCheckBoxModel extends AbstractCheckBoxModel {
private final STUList info;
private ArrayList<STUList> list1;
public SelectedCheckBoxModel(STUList info, ArrayList<STUList> list1) {
super();
this.info = info;
this.list1 = list1;
}
#Override
public boolean isSelected() {
// TODO Auto-generated method stub
return list1.contains(info);
}
#Override
public void select() {
// TODO Auto-generated method stub
list1.add(info);
}
#Override
public void unselect() {
// TODO Auto-generated method stub
list1.remove(info);
}
and i called it in my listview
check = new CheckBox("check", new SelectedCheckBoxModel(stu, list1));
item.add(check);
if this is not optimal please suggest
Thank You
I want to create an expandable list view Keeping some child visible,where as I want to show rest on click.
Please suggest what is the best approach in such scenario,if any custom element or any tutorial as such.
Many Thanks,
This will be helpful to you.
Adapter class:-
public class MyExpandableAdapter extends BaseExpandableListAdapter {
private Activity activity;
private ArrayList<Object> childtems;
private LayoutInflater inflater;
private ArrayList<String> parentItems, child;
public MyExpandableAdapter(ArrayList<String> parents,
ArrayList<Object> childern) {
this.parentItems = parents;
this.childtems = childern;
}
public void setInflater(LayoutInflater inflater, Activity activity) {
this.inflater = inflater;
this.activity = activity;
}
#Override
public View getChildView(int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
child = (ArrayList<String>) childtems.get(groupPosition);
TextView textView = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.group, null);
}
textView = (TextView) convertView.findViewById(R.id.textView1);
textView.setText(child.get(childPosition));
convertView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(activity, child.get(childPosition),
Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
#Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.row, null);
}
((CheckedTextView) convertView).setText(parentItems
.get(groupPosition));
((CheckedTextView) convertView).setChecked(isExpanded);
return convertView;
}
#Override
public Object getChild(int groupPosition, int childPosition) {
return null;
}
#Override
public long getChildId(int groupPosition, int childPosition) {
return 0;
}
#Override
public int getChildrenCount(int groupPosition) {
return ((ArrayList<String>) childtems.get(groupPosition)).size();
}
#Override
public Object getGroup(int groupPosition) {
return null;
}
#Override
public int getGroupCount() {
return parentItems.size();
}
#Override
public void onGroupCollapsed(int groupPosition) {
super.onGroupCollapsed(groupPosition);
}
#Override
public void onGroupExpanded(int groupPosition) {
super.onGroupExpanded(groupPosition);
}
#Override
public long getGroupId(int groupPosition) {
return 0;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
}
MainActivity is here.
public class MainActivity extends ExpandableListActivity {
private ArrayList<String> parentItems = new ArrayList<String>();
private ArrayList<Object> childItems = new ArrayList<Object>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// this is not really necessary as ExpandableListActivity contains
// an ExpandableList
// setContentView(R.layout.main);
ExpandableListView expandableList = getExpandableListView(); // you
// can
// use
// (ExpandableListView)
// findViewById(R.id.list)
expandableList.setDividerHeight(2);
expandableList.setGroupIndicator(null);
expandableList.setClickable(true);
setGroupParents();
setChildData();
MyExpandableAdapter adapter = new MyExpandableAdapter(parentItems,
childItems);
adapter.setInflater(
(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE),
this);
expandableList.setAdapter(adapter);
expandableList.setOnChildClickListener(this);
}
public void setGroupParents() {
parentItems.add("Android");
parentItems.add("Core Java");
parentItems.add("Desktop Java");
parentItems.add("Enterprise Java");
}
public void setChildData() {
// Android
ArrayList<String> child = new ArrayList<String>();
child.add("Core");
child.add("Games");
childItems.add(child);
// Core Java
child = new ArrayList<String>();
child.add("Apache");
child.add("Applet");
child.add("AspectJ");
child.add("Beans");
child.add("Crypto");
childItems.add(child);
// Desktop Java
child = new ArrayList<String>();
child.add("Accessibility");
child.add("AWT");
child.add("ImageIO");
child.add("Print");
childItems.add(child);
// Enterprise Java
child = new ArrayList<String>();
child.add("EJB3");
child.add("GWT");
child.add("Hibernate");
child.add("JSP");
childItems.add(child);
}
}
At start open the groups you want to be fixed then implement this , specify the the groups postion
expandableList.setOnGroupClickListener(new OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
if(groupPosition==your group position){
return true; // This way the expander cannot be collapsed
}else{
return false;
}
}
});
Override onGroupCollapsed and onGroupExpanded of the ExpandableListView based on your needs.
EDITED: In addition: implement the mentioned setOnGroupClickListener, store the groupIDs within your view, and suppress the collapsing in onGroupCollapsed.
I want to fire the "open root node" event on my current working CellTree, which now has the following behaviour:
#Override
public <T> NodeInfo<?> getNodeInfo(final T value) {
return new DefaultNodeInfo<Categoria>(
(value instanceof Categoria) ?
createBranchDataProvider((Categoria)value) :
rootDataProvider,
new CategoriaCell()
);
}
private AsyncDataProvider<Categoria> createRootDataProvider() {
AsyncDataProvider<Categoria> dataProvider = new AsyncDataProvider<Categoria>() {
#Override
protected void onRangeChanged(HasData<Categoria> display) {
AsyncCallback<Categoria[]> cb = new AsyncCallback<Categoria[]>() {
#Override
public void onSuccess(Categoria[] result) {
updateRowCount(result.length, true);
updateRowData(0, Arrays.asList(result));
}
#Override
public void onFailure(Throwable caught) {
Window.alert(caught.toString());
}
};
rpcService.getCategorie(cb);
}
};
return dataProvider;
}
How can I fire that "onRangeChanged" event, to refresh my level-1 nodes?
What is my convenience method missing?
private void updateTree() {
TreeNode rootTreeNode = cellTree.getRootTreeNode();
for (int i = 0; i < rootTreeNode.getChildCount(); i++) {
rootTreeNode.setChildOpen(i, false);
}
// HOW TO REFRESH LEVEL-1 NODES?
}
Working example. Add reference to DataProvider (and parent Node) (MyMenuItem and MyCell with DataProvider in my code). After adding element refresh parent.
public class MyMenuItem {
private String name;
private String action; //some data
private int level; //if needed
private ArrayList<MyMenuItem> list; //nodes childrens
private MyMenuItem parent; //track internal parent
private MyCell cell; //for refresh - reference to visual component
public void setCell(MyCell cell) {
this.cell = cell;
}
public void refresh() {
if(parent!=null) {
parent.refresh();
}
if (cell!=null) {
cell.refresh(); //refresh tree
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public MyMenuItem(String name, String action) {
super();
parent = null;
level = 0;
this.name = name;
this.action = action;
list = new ArrayList<MyMenuItem>();
}
public MyMenuItem(String name) {
this(name, "");
}
public void addSubMenu(MyMenuItem m) {
m.level = this.level+1;
m.parent = this;
list.add(m);
}
public boolean hasChildrens() {
return list.size()>0;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public ArrayList<MyMenuItem> getList() {
return list;
}
public MyMenuItem getParent() {
return parent;
}
}
public class MyTreeModel implements TreeViewModel {
private MyMenuItem officialRoot; //default not dynamic
private MyMenuItem studentRoot; //default not dynamic
private MyMenuItem testRoot; //default not dynamic
private MyMenuItem root;
public MyMenuItem getRoot() { // to set CellTree root
return root;
}
public MyTreeModel() {
root = new MyMenuItem("root");
// Default items
officialRoot = new MyMenuItem("Official"); //some basic static data
studentRoot = new MyMenuItem("Student");
testRoot = new MyMenuItem("Test");
root.addSubMenu(officialRoot);
root.addSubMenu(studentRoot);
root.addSubMenu(testRoot);
}
//example of add add logic
private void addNew(MyMenuItem myparent, String name, String uid) {
myparent.addSubMenu(new MyMenuItem(name, uid));
myparent.refresh(); //HERE refresh tree
}
#Override
public <T> NodeInfo<?> getNodeInfo(T value) {
ListDataProvider<MyMenuItem> dataProvider;
MyMenuItem myValue = null;
if (value == null) { // root is not set
dataProvider = new ListDataProvider<MyMenuItem>(root.getList());
} else {
myValue = (MyMenuItem) value;
dataProvider = new ListDataProvider<MyMenuItem>(myValue.getList());
}
MyCell cell = new MyCell(dataProvider); //HERE Add reference
if (myValue != null)
myValue.setCell(cell);
return new DefaultNodeInfo<MyMenuItem>(dataProvider, cell);
}
#Override
public boolean isLeaf(Object value) {
if (value instanceof MyMenuItem) {
MyMenuItem t = (MyMenuItem) value;
if (!t.hasChildrens())
return true;
return false;
}
return false;
}
}
public class MyCell extends AbstractCell<MyMenuItem> {
ListDataProvider<MyMenuItem> dataProvider; //for refresh
public MyCell(ListDataProvider<MyMenuItem> dataProvider) {
super("keydown","dblclick");
this.dataProvider = dataProvider;
}
public void refresh() {
dataProvider.refresh();
}
#Override
public void onBrowserEvent(Context context, Element parent, MyMenuItem value,
NativeEvent event, ValueUpdater<MyMenuItem> valueUpdater) {
if (value == null) {
return;
}
super.onBrowserEvent(context, parent, value, event, valueUpdater);
if ("click".equals(event.getType())) {
this.onEnterKeyDown(context, parent, value, event, valueUpdater);
}
if ("dblclick".equals(event.getType())) {
this.onEnterKeyDown(context, parent, value, event, valueUpdater);
}
}
#Override
public void render(Context context, MyMenuItem value, SafeHtmlBuilder sb) {
if (value == null) {
return;
}
sb.appendEscaped(value.getName());
//add HERE for better formating
}
#Override
protected void onEnterKeyDown(Context context, Element parent,
MyMenuItem value, NativeEvent event, ValueUpdater<MyMenuItem> valueUpdater) {
Window.alert("You clicked "+event.getType()+" " + value.getName());
}
}
in module add
treeModel = new MyTreeModel();
tree = new CellTree(treeModel,treeModel.getRoot());
The Level-1 nodes (I suppose you the mean below the root node) can not be refreshed the way you are doing it.
You have to store the instance of your dataProvider for the level-1 nodes somewhere.
Later when you refresh your list you have to update your stored dataProvider for your level-1 nodes.
The nodes below the level-1 can be refreshed the way you are doing it. Because as soon as you close the level 1 nodes (that is what you are doing in the updateTree method) and the next time you open it getNodeInfo will be called and the updated Subcategories will be retrieved and displayed in the CellTree.
UPDATE
For refreshing the CellWidgets which is attached to AsyncDataProvider you will probably have to extend the AsyncDataProvider and either extract the RPC call to a getData() method which is called in the onRangeChanged() method or create an interface with a refresh method and implement it in your custom AsyncDataProvider which calls the protected onRangeChanged() method.
hi all
i need a simple example show me how to add column of ClickableTextCells to cellTable
thanks.
Column<YerValueObject, String> newCol = new Column<YerValueObject, String>(new ClickableTextCell()) {
#Override
public String getValue(YearValueObject obj) {
return obj.someMethod();
}
};
newCol.setFieldUpdater(new FieldUpdater<YerValueObject, String>() {
#Override
public void update(int index, YerValueObject obj, String value) {
//do whatever you need to here...
}
});
table.addColumn(newCol, "ClickColumn");
this is the solution if you need to add clickableTextCell to cellTable
// ClickableTextCell
ClickableTextCell anchorcolumn = new ClickableTextCell();
table.addColumn(addColumn(anchorcolumn, new GetValue<String>() {
public String getValue(Contact contact) {
return "Click " + contact.anchor;
}
}, new FieldUpdater<Contact, String>() {
public void update(int index, Contact object, String value) {
Window.alert("You clicked " + object.name);
}
}), "Anchor");
private <C> Column<Contact, C> addColumn(Cell<C> cell,final GetValue<C> getter,
FieldUpdater<Contact, C> fieldUpdater) {
Column<Contact, C> column = new Column<Contact, C>(cell) {
#Override
public C getValue(Contact object) {
return getter.getValue(object);
}
};
column.setFieldUpdater(fieldUpdater);
return column;
}
private static interface GetValue<C> {
C getValue(Contact contact);
}
// A simple data type that represents a contact.
private static class Contact {
private final String address;
private final String name;
private final String anchor;
public Contact(String name, String address, String anchor) {
this.name = name;
this.address = address;
this.anchor = anchor;
}
}
Create a Column overriding the onBrowserEvent method.
Like this:
new Column<T, String>(new TextCell()) {
#Override
public String getValue(T object) {
return object.getProperty();
}
#Override
public void onBrowserEvent(Context context, Element elem, T object, NativeEvent event) {
// TODO You can check which event you want to catch
Window.open("http://www.stackoverflow.com", "StackOverFlow", "");
}
};
I'm trying to create a modal confirmation dialog box. I'd like it to work like Window.confirm(""), where I can just call it, and get a boolean response.
My trouble is I'm not sure how to do it. I'm trying to use MVP in my application. Here is the code I have so far:
public class DialogBoxPresenter implements Presenter {
public interface Display {
Label getDialogText();
Button getAffirmativeButton();
Button getCancelButton();
Widget asWidget();
public void center();
public void hide();
public void setHeader(String text);
}
private Display display;
private String header;
private String dialogText;
private String cancelButtonText;
private String affirmativeButtonText;
protected DialogBoxPresenter() {
}
public DialogBoxPresenter(Display display, String header, String dialogText, String cancelButtonText, String affirmativeButtonText) {
this.display = display;
this.header = header;
this.dialogText = dialogText;
this.cancelButtonText = cancelButtonText;
this.affirmativeButtonText = affirmativeButtonText;
bind();
}
public DialogBoxPresenter(Display display, String header, String dialogText) {
this.display = display;
this.header = header;
this.dialogText = dialogText;
this.cancelButtonText = "Cancel";
this.affirmativeButtonText = "OK";
bind();
}
private void bind() {
this.display.getDialogText().setText(dialogText);
this.display.getAffirmativeButton().setText(affirmativeButtonText);
this.display.getCancelButton().setText(cancelButtonText);
this.display.setHeader(header);
addClickHandlers();
}
private void addClickHandlers() {
this.display.getAffirmativeButton().addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
doAffirmative();
}
});
this.display.getCancelButton().addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
doCancel();
}
});
}
private void doAffirmative() {
//do something
display.hide();
}
private void doCancel() {
//do something
display.hide();
}
public void init() {
display.center();
}
#Override
public void go(HasWidgets container) {
container.clear();
container.add(display.asWidget());
}
}
and my view:
public class DialogBoxView extends DialogBox implements DialogBoxPresenter.Display {
private Label dialogText;
private Button affirmativeButton;
private Button cancelButton;
private VerticalPanel container;
public DialogBoxView() {
//init items
dialogText = new Label();
affirmativeButton = new Button();
cancelButton = new Button();
container = new VerticalPanel();
setGlassEnabled(true);
setAnimationEnabled(true);
setModal(false);
init();
}
private void init() {
//add items
container.add(dialogText);
HorizontalPanel hp = new HorizontalPanel();
hp.add(affirmativeButton);
hp.add(cancelButton);
container.add(hp);
this.add(container);
}
#Override
public Widget asWidget() {
return this;
}
#Override
public Label getDialogText() {
return dialogText;
}
#Override
public Button getAffirmativeButton() {
return affirmativeButton;
}
#Override
public Button getCancelButton() {
return cancelButton;
}
#Override
public void setHeader(String text) {
this.setText(text);
}
}
You're not going to be able to have it work in exactly the same way as Window.confirm(). The problem is that all of the javascript in a web page runs in a single thread. You'll notice that as long as a standard confirm dialog is open, the rest of the page goes dead. That's because the one javascript thread is blocked, waiting for confirm() to return. If you were to create a similar method for your dialog, as long as it was waiting for that method to return no user generated events would be processed and so your dialog wouldn't work. I hope that makes sense.
The best you will be able to do is similar to what the GWT library does for RPC calls -- the AsyncCallback interface. You could even reuse that interface yourself, or you might prefer to roll your own:
public interface DialogCallback {
void onOk();
void onCancel();
}
Instead of Window.confirm(String), your method signature will be more like Dialog.confirm(String,DialogCallback). Then your dialog just keeps a reference to the callback that's passed in, and where you have // do something in your code you make calls to onOk and onCancel.
Here is the code I have working if anyone is curious.
public class DialogBoxPresenter implements Presenter {
public interface Display {
Label getDialogText();
Button getAffirmativeButton();
Button getCancelButton();
Widget asWidget();
public void center();
public void hide();
public void setHeader(String text);
}
private Display display;
private String header;
private String dialogText;
private String cancelButtonText;
private String affirmativeButtonText;
private ConfirmDialogCallback confirmCallback;
private AlertDialogCallback alertCallback;
protected DialogBoxPresenter() {
}
public DialogBoxPresenter(Display display, String header, String dialogText, String cancelButtonText, String affirmativeButtonText, ConfirmDialogCallback callback) {
this.display = display;
this.header = header;
this.dialogText = dialogText;
this.cancelButtonText = cancelButtonText;
this.affirmativeButtonText = affirmativeButtonText;
this.confirmCallback = callback;
bind();
}
public DialogBoxPresenter(Display display, String header, String dialogText, String affirmativeButtonText, AlertDialogCallback callback) {
this.display = display;
this.header = header;
this.dialogText = dialogText;
this.affirmativeButtonText = affirmativeButtonText;
this.alertCallback = callback;
this.display.getCancelButton().setVisible(false);
bind();
}
private void bind() {
this.display.getDialogText().setText(dialogText);
this.display.getAffirmativeButton().setText(affirmativeButtonText);
this.display.getCancelButton().setText(cancelButtonText);
this.display.setHeader(header);
addClickHandlers();
}
private void addClickHandlers() {
this.display.getAffirmativeButton().addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
doAffirmative();
}
});
this.display.getCancelButton().addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
doCancel();
}
});
}
private void doAffirmative() {
if (confirmCallback != null) {
confirmCallback.onAffirmative();
} else {
alertCallback.onAffirmative();
}
display.hide();
}
private void doCancel() {
confirmCallback.onCancel();
display.hide();
}
public void init() {
display.center();
}
#Override
public void go(HasWidgets container) {
container.clear();
container.add(display.asWidget());
}
}
public class DialogBoxView extends DialogBox implements DialogBoxPresenter.Display {
private Label dialogText;
private Button affirmativeButton;
private Button cancelButton;
private VerticalPanel container;
public DialogBoxView() {
//init items
dialogText = new Label();
affirmativeButton = new Button();
cancelButton = new Button();
container = new VerticalPanel();
setGlassEnabled(true);
setAnimationEnabled(true);
setModal(false);
init();
}
private void init() {
//add items
container.add(dialogText);
HorizontalPanel hp = new HorizontalPanel();
hp.add(affirmativeButton);
hp.add(cancelButton);
container.add(hp);
this.add(container);
}
#Override
public Widget asWidget() {
return this;
}
#Override
public Label getDialogText() {
return dialogText;
}
#Override
public Button getAffirmativeButton() {
return affirmativeButton;
}
#Override
public Button getCancelButton() {
return cancelButton;
}
#Override
public void setHeader(String text) {
this.setText(text);
}
}
public class DialogBoxWidget implements LensooConstant {
private static DialogBoxView view = null;
private static DialogBoxPresenter presenter = null;
public static DialogBoxPresenter confirm(String header, String dialogText, String cancelButtonText, String affirmativeButtonText, ConfirmDialogCallback callback) {
view = new DialogBoxView();
presenter = new DialogBoxPresenter(view, header, dialogText, cancelButtonText, affirmativeButtonText, callback);
presenter.init();
return presenter;
}
public static DialogBoxPresenter confirm(String header, String dialogText, ConfirmDialogCallback callback) {
return DialogBoxWidget.confirm(header, dialogText, constants.cancelButton(), constants.okButton(), callback);
}
public static DialogBoxPresenter alert(String header, String dialogText, String affirmativeButtonText, AlertDialogCallback callback) {
view = new DialogBoxView();
presenter = new DialogBoxPresenter(view, header, dialogText, affirmativeButtonText, callback);
presenter.init();
return presenter;
}
public static DialogBoxPresenter alert(String header, String dialogText, AlertDialogCallback callback) {
return DialogBoxWidget.alert(header, dialogText, constants.okButton(), callback);
}
protected DialogBoxWidget() {
}
}
public interface AlertDialogCallback {
void onAffirmative();
}
public interface ConfirmDialogCallback {
void onAffirmative();
void onCancel();
}