CellWidget not getting displayed - gwt

I am trying to make a basic cellbrowser widget work in my App. For now just the Structure so that I can replace it later with something meaningfull.
I looked up the samples and implemented one however when I try integarting it in my Application, it wont work!
Here is the part of code. What is the problem? Why cant I see the widget?
public class ListViewImpl extends Composite implements ListView
{
private static ListViewImplUiBinder uiBinder = GWT
.create(ListViewImplUiBinder.class);
interface ListViewImplUiBinder extends UiBinder<Widget, ListViewImpl>
{
}
private Presenter presenter;
#UiField(provided=true)
CellBrowser cellbrowser;
public ListViewImpl()
{
TreeViewModel model = new ListTreeViewModel();
cellbrowser=new CellBrowser(model,null);
cellbrowser.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
cellbrowser.setAnimationEnabled(true);
initWidget(uiBinder.createAndBindUi(this));
}
#Override
public void setPresenter(Presenter presenter)
{
this.presenter=presenter;
}
#Override
public Widget asWidget() {
return this;
}
}
The Uibinder file goes as -->
<ui:style>
.browser {
border: 1px solid #ccc;
}
.out
{
outline:#ccc solid thick;
}
</ui:style>
<g:HTMLPanel styleName='{style.out}' >
<c:CellBrowser addStyleNames='{style.browser}' defaultColumnWidth='300' ui:field='cellbrowser' />
</g:HTMLPanel>
The ListTreeView model class is perfect as when I use the code in a standalone application and add CellBrowser to RootLayoutPanel. It works!

CellBrowser is a RequiresResize widget (it uses a SplitLayoutPanel internally), so just like with all RequiresResize widget, you have to either put it within a ProvidesResize widget, or give it explicit dimensions.

Related

why can't i hide DialogBox in UiBinder in GWT?

in Test.ui.xml
<g:DialogBox ui:field="wishlistDialogBox" autoHide="true">
<g:caption>Test</g:caption>
<g:HTMLPanel> some widgets..</g:HTMLPanel>
</g:DialogBox>
After running, the application still show the DialogBox, so I tried to set hide for "wishlistDialogBox" in TestView.java but it didn't work.
#UiField DialogBox wishlistDialogBox;
#Inject
public TestView(final Binder binder) {
widget = binder.createAndBindUi(this);
wishlistDialogBox.hide();
}
Then i set hide for it in TestPresenter.java but it still didn't work
#Override
protected void onBind() {
super.onBind();
getView().getWishlistDialogBox().hide();
}
What's wrong, Goodle didn't explain it at all.
In addition, how to reuse the DialogBox?
DialogBox (and PopupPanels in general) does not work like any other widget when speaking about adding them to the DOM. You should never attach them directly to it (i.e., panel.add(yourDialogBox) or inside a UiBinder XML file) as you did. Instead you should create them, and simply call hide()/show(), and the like methods, to get it displayed/hidden (i.e., attached/detached at the end of/from the DOM).
Something that works for me is creating a Dialogbox separately from any other widgets. So it has its own Java file and its own ui.xml file :
UiBinder xml file:
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:DialogBox ui:field="dialog">
<g:caption>My Dialog</g:caption>
<g:HTMLPanel>
<g:Button ui:field="closeButton" text="close" />
</g:HTMLPanel>
</g:DialogBox>
</ui:UiBinder>
Java file:
public class MyDialog { // here you do not inherit anything
private static MyDialogUiBinder uiBinder = GWT.create(MyDialogUiBinder.class);
interface MyDialogUiBinder extends UiBinder<Widget, MyDialog> {
}
#UiField
DialogBox dialog;
#UiField
Button closeButton;
public MyDialog() {
// make cast to DialogBox
dialog = (DialogBox) (uiBinder.createAndBindUi(this));
}
public void hide() {
dialog.hide();
}
public void show() {
dialog.center();
}
#UiHandler("closeButton")
public void onClick(ClickEvent event) {
hide();
}
}
Finally i figured out a way, that is to put the DialogBox into a invisible HTMLPanel
<g:HTMLPanel visible="false">
<g:DialogBox ui:field="wishlistDialogBox" autoHide="true">
<g:caption>Test</g:caption>
<g:HTMLPanel> some widgets..</g:HTMLPanel>
</g:DialogBox>
</g:HTMLPanel>
Then just call show & hide DialogBox as usual & it will show the DialogBox even the DialogBox was wrapped inside an invisible HTMLPanel.
getView().getWishlistDialogBox().show();

UIBinder with Widget

I am trying to add a widget to a panel using UIBinder but the composite simply doesn't load, here is my xml:
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:my='urn:import:com.abc.client.test.ui'>
<g:HTMLPanel ui:field="mainLayoutPanel">
<g:SimplePanel ui:field="menuPanel" >
<my:MainMenuViewImpl ui:field="mainMenu"/>
</g:SimplePanel>
<!-- the widget causing the issue -->
<my:FinancialsNav ui:field="nav"/>
<g:SimplePanel ui:field="mainPanel" />
</g:HTMLPanel>
</ui:UiBinder>
The corresponding java class:
public class AppLayoutImpl extends Composite implements AppLayout{
#UiField
HTMLPanel mainLayoutPanel;
interface AppLayoutUiBinder extends UiBinder<Widget,AppLayoutImpl>{}
private static AppLayoutUiBinder binder=GWT.create(AppLayoutUiBinder.class);
#UiField
SimplePanel menuPanel;// nav at the top
#UiField(provided=true)
FinancialsNav nav;// nav on the side
#UiField
SimplePanel mainPanel;// center
#UiField(provided=true)
MainMenuViewImpl mainMenu;
public AppLayoutImpl(ClientFactory clientFactory){
mainMenu=clientFactory.getMainMenuView();
nav=clientFactory.getNav();
initWidget(binder.createAndBindUi(this));
}
#Override
public Widget asWidget(){
return this;
}
}
And the Widget causing the issue:
public class FinancialsNav extends Composite implements ClickHandler{
private VerticalPanel nav=new VerticalPanel();
// Operations
private DisclosurePanel operationsWrapper=new DisclosurePanel(Proto2.constants.financials_navigation_operations());
private NavButton product=new NavButton(Proto2.constants.financials_navigation_products(),
SharedUtilities.PRODUCT_TOKEN);
private NavButton generalOptions=new NavButton(Proto2.constants.financials_navigation_generalOptions(),"");
private ArrayList<NavButton[]> buttons;
private NavButton[] operationsButtons={product,vc,fc,emp,others};
//...
private NavButton[] optionsButtons={generalOptions};
private final EventBus bus;
public FinancialsNav(EventBus bus){
this.bus=bus;
buildNav();
initWidget(nav);
}
private void buildNav(){
buttons=new ArrayList<NavButton[]>();
buttons.add(operationsButtons);
//...
buttons.add(optionsButtons);
int n=buttons.size();
int nn;
for(int i=0;i<n;i++){
nn=buttons.get(i).length;
for(int j=0;j<nn;j++){
(buttons.get(i)[j]).addClickHandler(this);
(buttons.get(i)[j]).setStylePrimaryName(NAV_BUTTON_STYLE);
if(i==0){
operationsWrapper.add(buttons.get(i)[j]);
//...
}else if(i==4){
optionsWrapper.add(buttons.get(i)[j]);
}
}
}
nav.add(operationsWrapper);
// ...
nav.add(optionsWrapper);
}
The FinancialsNav widget works fine when not used with UIBinder and the rest of AppLayout works as expected when the FinancialsNav isn't there.
I spent hours on this looking at various tutorials and examples but simply could not find what is wrong with the code. I also tried various workaround such as declaring a panel in the UIBinder instead of the FinancialsNav and the adding the nav to the panel.
Also everything is in the same package so it shouldn't be an import issue.
Any help would be much appreciated...
Here is the clientFactory
public class ClientFactoryImpl implements ClientFactory{
private static final EventBus eventBus=new SimpleEventBus();
private static final PlaceController placeController=new PlaceController(eventBus);
private static final CreatePlanServiceAsync createPlanService=GWT.create(CreatePlanService.class);
private static final FinancialsNav navView=new FinancialsNav(eventBus);
private static final MainMenuViewImpl mainMenuView=new MainMenuViewImpl();
#Override
public EventBus getEventBus(){
return eventBus;
}
#Override
public PlaceController getPlaceController(){
return placeController;
}
#Override
public FinancialsNav getNav(){
return navView;
}
#Override
public MainMenuViewImpl getMainMenuView(){
return mainMenuView;
}
#Override
public CreatePlanServiceAsync getCreatePlanService(){
return createPlanService;
}
}
FinancialsNav widgets has constructor with arguments. So create no argument constructor.
The entry <my:FinancialsNav ui:field="nav"/> is equals to new FinancialsNav().
In most cases this means that they must be default instantiable; that is, they must provide a zero-argument constructor. you have to pass argument
/** Used by MyUiBinder to instantiate FinancialsNav */
#UiFactory FinancialsNav makeFinancialsNav() { // method name is insignificant. do start with make
return new FinancialsNav(eventBus);
}
Refer Using a widget that requires constructor args
Can you show clientFactory code!!
Ok I found the error, actually not directly related to UIBinder.
Simultaneously to implementing UIBinder I was trying to reduce the number of tables used by the panels in my app.
As I noticed that the disclosure panel is based on a table I removed an intermediary vertical panel I had in the FinancialsNav.
Hence having DisclosurePanel --> Buttons instead of DisclosurePanel --> VerticalPanel --> Buttons. And that is causing the entire block not to show.
#adenoyelle and #bumika: thank you for help

Disclosure panel header widget client bundle,#sprite is not working

I am having DisclosurePanel, as header content i have HorizontalPanel which is applied style, these styles is having background image, which uses ClientBundle with #sprite.
But issue is the style is not applying for the header widget (Horizontal Panel)
here my code goes
Entry class
public class Test implements EntryPoint {
/**
* This is the entry point method.
*/
public void onModuleLoad() {
TestClientBundle.INSTANCE.testCsss().ensureInjected();
DisclosurePanel dp = new DisclosurePanel();
HorizontalPanel hp = new HorizontalPanel();
dp.setStyleName("blue");
Label l = new Label("testing the DP with IMG-CSS bundle");
hp.add(l);
dp.setHeader(hp);
dp.setContent(new Label("Body"));
RootPanel.get().add(dp);
}
}
ClientBundle interface
public interface TestClientBundle extends ClientBundle {
TestClientBundle INSTANCE = GWT.create(TestClientBundle.class);
#Source("blue.jpg")
public ImageResource blue();
#Source("test.css")
public CssResource testCsss();
}
Css File
#external .blue;
#sprite .blue {
gwt-image: 'blue';
cursor: pointer;
text-decoration: none;
}
Is it known issue in GWT or my code is wrong?
Instead of
dp.setStyleName("gates_playbookimage_blue");
you need to have a way to refer to that css class name - you need a CssResource interface:
public interface MyCssResource extends CssResource {
String gates_playbookimage_blue();
}
Reference this from your clientbundle instead of CssResource:
public interface TestClientBundle extends ClientBundle {
TestClientBundle INSTANCE = GWT.create(TestClientBundle.class);
#Source("playbook_blue.jpg")
public ImageResource playbookBlue();
#Source("test.css")
public MyCssResource testCsss();
}
Now you can do this:
MyCssResource css = TestClientBundle.INSTANCE.testCsss();
css.ensureInjected();
//...
dp.setStyleName(css.gates_playbookimage_blue());
This will let the css compiler rewrite your css as needed, and be sure to pass in the rewritten class name to your widget.

What is the proper way to use gwt-bootstrap modal with gwt-platform?

I am constructiong an webapp with Google Web Toolkit using GWT-Platform and GWT-Bootstrap frameworks. Mostly it has been almost flawless until I tried to implement a popup. These frameworks' undestanding of popups seems to be quite different.
GWT-Platform expects a popup widget itself to be an instance of com.google.gwt.user.client.ui.PopupPanel when using the GWTP's RevealRootPopupContentEvent.fire(source, content) or a presenter's addToPopupSlot(child) method.
GWT-Bootstrap's Modal is used like any other widget that is added to the underlying panel but my goal is it to have a separate presenter and view and to possibly fetch it asynchrously with AsyncProvider.
I have tried to make it as a PresenterWidget and using addToSlot(slot, content) to reveal it but it doesn't look quite right. Not all of the styles are applied this way and the close icon (×), doesn't work for example.
I think I am not the first one trying to do something like that so maybe someone has figured out a proper way to make it work.
Thanks!
You have to create a view:
public class MyPopupView extends PopupViewImpl implements MyView {
protected Widget widget;
public interface MyPopupViewUiBinder extends
UiBinder<Widget, MyPopupView> {
}
#UiField(provided = true)
Modal dialogBox;
private MyPresenter presenter;
#Inject
public MyPopupView(final MyPopupViewUiBinder uiBinder,
final EventBus eventBus) {
super(eventBus);
setUpDialog(); // Provides UiField => Before initWidgets
initWidget(uiBinder.createAndBindUi(this));
}
// DialogBox must be overridden to let the presenter handle changes onUnload
private void setUpDialog() {
dialogBox = new Modal() {
#Override
protected void onUnload() {
MyPopupView.this.hide();
}
};
dialogBox.setTitle("Some title");
}
#Override
public void setPresenter(final MyPresenter presenter) {
this.presenter = presenter;
}
#Override
public final void hide() {
dialogBox.hide();
presenter.hide();
}
#Override
public void setAutoHideOnNavigationEventEnabled(final boolean autoHide) {
// TODO Auto-generated method stub
}
#Override
public void setCloseHandler(
final PopupViewCloseHandler popupViewCloseHandler) {
// TODO Auto-generated method stub
}
#Override
public void setPosition(final int left, final int top) {
// TODO Auto-generated method stub
}
#Override
public void show() {
dialogBox.show();
}
#Override
public void center() {
dialogBox.show();
}
#Override
public Widget asWidget() {
return widget;
}
protected final void initWidget(final Widget widget) {
this.widget = widget;
}
}
And a UIBinder file:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:b='urn:import:com.github.gwtbootstrap.client.ui'>
<b:Modal title="Some Title" ui:field="dialogBox">
<!-- Your content -->
</b:Modal>
</ui:UiBinder>
Your gwtp popup presenter has a view that extends PopUpViewImpl which implements PopupView, and uses a lot of the methods of that interface for displaying the popup (asPopupPanel(), show(), center(), etc).
I'm just starting to get to know gwt-bootstrap (looks great +caalos0), but it seems that Modal doesn't implement PopupView, and therefore cannot be passed to addToPopupSlot in a way it would be displayed automatically by gwtp.
as for the addToSlot() issue, are you using RootLayoutPanel or RootPanel?
it could be the reason for addToSlot not working properly, since the gwt-bootstrap Modal widget is attached to the RootPanel on initialization, this can cause weird layout behavior along with an application using RootLayoutPanel as base.
I would try to extend the Modal component, let it implement PopUpView, add it as a field on the PopUpViewImpl attached to your popup presenter, and override the PopUpViewImpl asPopupPanel() function to return the new extended Modal.
Based on the answer by #dominik I did some improvements, see my Gist. It contains some abstract base classes that can be used for any Modal/PopupView implementation. It's a bit more complex but also cleaner because we don't pass the whole Presenter to the View. The interface for the View to interact with the Presenter when the modal is closed is HasModalUnbind.
You would use these classes as follows. Example presenter:
public class ErrorModalPresenter extends ModalPopupPresenter<ErrorModalPresenter.MyView> {
public interface MyView extends ModalPopupView {
DivElement getErrorMessage();
}
private final ErrorEvent error;
#Inject
public ErrorModalPresenter(final EventBus eventBus,
final MyView view,
#Assisted final ErrorEvent error) {
super(eventBus, view);
this.error = error;
}
#Override
public void unbindModal() {
ErrorDismissEvent.fire(this, this);
}
#Override
protected void onBind() {
super.onBind();
//noinspection ThrowableResultOfMethodCallIgnored
getView().getErrorMessage().setInnerText(error.getCause().getMessage());
}
}
Example view:
public class ErrorModalView extends ModalPopupViewImpl implements ErrorModalPresenter.MyView {
#UiField(provided = true)
Modal errorModal;
#UiField
DivElement errorMessage;
interface Binder extends UiBinder<Widget, ErrorModalView> {}
#Inject
public ErrorModalView(final EventBus eventBus,
final Binder uiBinder) {
super(eventBus);
errorModal = initModal();
initWidget(uiBinder.createAndBindUi(this));
}
#Override
public DivElement getErrorMessage() {
return errorMessage;
}
}
And the UiBinder XML just for the record:
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
xmlns:b='urn:import:com.github.gwtbootstrap.client.ui'>
<b:Modal ui:field='errorModal' title='Error'>
<g:HTML>
<div ui:field='errorMessage'/>
</g:HTML>
<b:ModalFooter>
<b:Button text='Close' dismiss='MODAL'/>
</b:ModalFooter>
</b:Modal>
</ui:UiBinder>
In unbindModal() of ErrorModalPresenter I fire an event which is caught by the parent presenter of ErrorModalPresenter. There the modal presenter is removed from a container and then unbind() is called on the presenter. Of course any other solution is possible in unbindModal().
The base classes assume that modals are one-shot modals that will be removed once they're hidden. This behaviour can be changed in initModal() of ModalPopupViewImpl.
I believe you will have to made some Glue Code to made it works.
I never used GWT-Platform popups, so I dont know exactly how, but I believe you will have to made a new Class extending PopupPresenter, and made what's needed to made it work.
Also, I was thinking about GWT-Platform days ago... and I'm pretty sure that when first release of GWT-Platform is out, I'll create a new project to made these necessary glue codes.
If you need any help with this, please contact me.
Thanks, sorry about the poor gwt-platform support.

Gwt-query doesn't work for my MVP.

I dived to the gwt world a few monthes ago and now am trying to use the gwt-query library.
I followed this tutorial: http://code.google.com/p/gwtquery/wiki/GettingStarted
Because I am working in Modle-View-Presenter, I tried implementing the above tutorial in my View (that is bound to the ..View.ui.xml), But it dosent seems to work.
I tried creating a lable, and then run the code:
List allGwtLabels = $(".gwt-Label").widgets();
but it selects nothing!
I think I have to point somehow where I want the qwtQuery to search for the widgets (point to my specific ui.xml file)
What am I doing wrong?
Thanks in advance. Below is my code of my Presenter + View + xml that dosent work:
//================================Presenter=================================:
public class QueryPresenter extends
Presenter<QueryPresenter.MyView, QueryPresenter.MyProxy> {
public interface MyView extends View {
}
#ProxyCodeSplit
#NameToken(NameTokens.query)
public interface MyProxy extends ProxyPlace<QueryPresenter> {
}
#Inject
public QueryPresenter(final EventBus eventBus, final MyView view,
final MyProxy proxy) {
super(eventBus, view, proxy);
}
#Override
protected void revealInParent() {
RevealRootContentEvent.fire(this, this);
}
#Override
protected void onBind() {
super.onBind();
}
}
//====================================View============================================:
public class QueryView extends ViewImpl implements QueryPresenter.MyView {
private final Widget widget;
public interface Binder extends UiBinder<Widget, QueryView> {
}
#Inject
public QueryView(final Binder binder) {
widget = binder.createAndBindUi(this);
List<Widget> allGwtLabels = $(".gwt-Label").widgets(); //Doesn't Work!!
//Also doesn't work!!
Label label = new Label("Click on me and I will disappear");
$(label).click(new Function() {
#Override
public void f(Widget w) {
//fade out the label
$(w).fadeOut(1000);
}
});
_html.add(label);
//retrieve all attached gwt labels
}
#Override
public Widget asWidget() {
return widget;
}
#UiField Label _label;
#UiField HTMLPanel _html;
}
//==================xml file===============================
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'
ui:generateFormat='com.google.gwt.i18n.rebind.format.PropertiesFormat'
ui:generateKeys='com.google.gwt.i18n.rebind.keygen.MD5KeyGenerator'
ui:generateLocales='default'>
<g:HTMLPanel ui:field="_html">
<script type="text/javascript" language="javascript" src="gquerytest/gquerytest.nocache.js"></script>
<g:Label text="hey" ui:field="_label"/>
</g:HTMLPanel>
</ui:UiBinder>
try : List allGwtLabels = $(".gwt-Label", widget).widgets();
You have to specify the container of your elements as the elements are not attached to the dom when you try to query them.