Showing posts with label GWT. Show all posts
Showing posts with label GWT. Show all posts
0

GXT 3 Date Field Min & Max Date

I want to set min dan max date for datefield and want it disable the selection of dates out of specified range.

DateField dateField = new DateField(new DateTimePropertyEditor(DateTimeFormat.getFormat("dd-MMM-yyyy")));
dateField.getDatePicker().setMinDate(mindate);
dateField.getDatePicker().setMaxDate(maxdDate);
        
0

GXT Grid Anchor Cell

In previous post, I wrote about my solution to render image & link in grid cell.
This is the generic class to handle it.

import java.util.HashSet;
import java.util.Set;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sencha.gxt.core.client.ValueProvider;

public class AnchorLinkCell<T> extends AbstractCell<T> {

    String imgURL = "";
    String styleClass = "";
    AsyncCallback<T> callback;
    ValueProvider<T, String> vp;

    public AnchorLinkCell(String imgURL, ValueProvider<T, String> vp, String styleClass, AsyncCallback<T> callback) {
        this.imgURL = imgURL;
        this.callback = callback;
        this.styleClass = styleClass;
        this.vp = vp;
    }

    @Override
    public void render(com.google.gwt.cell.client.Cell.Context context, T value, SafeHtmlBuilder sb) {
        sb.appendHtmlConstant("<div class=\"" + this.styleClass + "\" style='cursor: pointer'/>");
        if (imgURL != "") {
            sb.appendHtmlConstant("<img src='" + imgURL + "' style='cursor: pointer'/> ");
        }
        sb.append(SafeHtmlUtils.fromTrustedString(this.vp.getValue(value)));
        sb.appendHtmlConstant("</div>");
    }

    @Override
    public Set<String> getConsumedEvents() {
        Set<String> events = new HashSet<String>();
        events.add("click");
        return events;
    }

    @Override
    public void onBrowserEvent(com.google.gwt.cell.client.Cell.Context context, Element parent, T value, NativeEvent event, ValueUpdater<T> valueUpdater) {
        // TODO Auto-generated method stub
        super.onBrowserEvent(context, parent, value, event, valueUpdater);
        if (parent.getFirstChildElement().isOrHasChild(Element.as(event.getEventTarget()))) {
            this.callback.onSuccess(value);
        }
    }
}


Steps :

1. Declare column config with bean parameters and set the value as the identity of the bean.
ColumnConfig<PremiseBean, PremiseBean> prm_companyColumn = new ColumnConfig<PremiseBean, PremiseBean>(props.identity(), 150,"Company Name");
        

2. This can be done by adding an identity value provider in the property access interface.
IdentityValueProvider<PremiseBean> identity();


3. Declare the AnchorLinkCell and set the column cell.
AnchorLinkCell<PremiseBean> acLink=new AnchorLinkCell<PremiseBeanHelper.PremiseBean>("images/icons/add.png",props.prm_name(), "myLinkStyleNameinCSS", new AsyncCallback<PremiseBean>() {

    @Override
    public void onFailure(Throwable caught) {
        Application.handleException(caught);                
    }

    @Override
    public void onSuccess(PremiseBean result) {
        Info.display("AnchorLinkCall Test", result.getPk());                                
    }
});

prm_companyColumn.setCell(acLink);

4. Do the rest steps for the grid


0

GXT3 Grid Cell with clickable Image and hyperlink

Reference:
  1. http://stackoverflow.com/questions/18951897/gwt-imagecell-change-image-dynamically-in-a-datagrid-or-celltable
  2. http://stackoverflow.com/questions/4691801/how-can-i-render-a-clickabletextcell-as-an-anchor-in-a-gwt-celltable
  3. http://www.gwtproject.org/doc/latest/DevGuideUiCustomCells.html#cell-onBrowserEvent
I want to make the cell table in a grid to show icon and link in a column.
I tried to use anchor but unsuccessful. The cell grid only render text & image but not the event.
I found a solution using ImageCell.
Steps :

1. Set columnconfig
2. Declare ImageCell object
3. override render subroutine
4. Override getConsumedEvents - to expose click event
5.Override onBrowserEvent to handle the event

In this example, it's only handle the first child element, so I just group the image & link in a div.


ColumnConfig<PremiseBean, String> prm_nameColumn = new ColumnConfig<PremiseBean, String>(props.prm_name(), 150, "Name");
        
ImageCell ic = new ImageCell() {

    @Override
    public void render(com.google.gwt.cell.client.Cell.Context context, String value, SafeHtmlBuilder sb) {
        sb.appendHtmlConstant("<div class=\"myClickableCellTestStyle\" style='cursor: pointer'/>");
        sb.appendHtmlConstant("<img src='images/icons/add.png' style='cursor: pointer'/> ");
        sb.append(SafeHtmlUtils.fromTrustedString(value));
        sb.appendHtmlConstant("</div>");
    }

    @Override
    public Set<String> getConsumedEvents() {
        Set<String> events = new HashSet<String>();
        events.add("click");
        return events;
    }

    @Override
    public void onBrowserEvent(com.google.gwt.cell.client.Cell.Context context, Element parent, String value, NativeEvent event, ValueUpdater<String> valueUpdater) {
        super.onBrowserEvent(context, parent, value, event, valueUpdater);
        if (parent.getFirstChildElement().isOrHasChild(Element.as(event.getEventTarget()))) {
            Console.writeLine("OnEvent");
            Info.display("Test", value);
        }
    }
};
prm_nameColumn.setCell(ic);


add style to css.


.myClickableCellTestStyle{
    text-decoration:underline;
}
0

GWT - Add touch support to canvas

I have worked in the image viewer with support GWT scroll and touch.
The audience images using canvas + SVG transformation is detected so that the image can be panned and zoomed.No problems with scrolls, but I have a problem when showing images on smart phones.I have tried several other methods to handle events on canvas in GWT but failed.

Finally, I found an example of event handling in native JS and give a try. Luckyly it works.
I lost the URL of the referring page, but I'll try to find and update this post later.

The example :
I put all the event declaration in a function.
private native void attachTouch(JavaScriptObject ele) /*-{
    var ref = this;
    ele.ontouchstart = function(evt) {
      evt.preventDefault();
      var x2=-100;
      var y2=-100;
      if(evt.touches.length > 1){
        x2=evt.touches[1].pageX;
        y2=evt.touches[1].pageY;
      }
      ref.@net.vcari.webipc.client.graphics.ImageViewerSvgPanel::setInitialTouch(IIII)(evt.touches[0].pageX, evt.touches[0].pageY,x2,y2);
    }
    ele.ontouchmove = function(evt) {
      evt.preventDefault();
      var x2=-100;
      var y2=-100;
      if(evt.touches.length > 1){
        x2=evt.touches[1].pageX;
        y2=evt.touches[1].pageY;
      }
      ref.@net.vcari.webipc.client.graphics.ImageViewerSvgPanel::onTouchMove(IIII)(evt.touches[0].pageX, evt.touches[0].pageY,x2,y2);
    }
    ele.ontouchend = function(evt) {
      evt.preventDefault();
      ref.@net.vcari.webipc.client.graphics.ImageViewerSvgPanel::onEndTouch(II)(evt.pageX, evt.pageY);
    }
  }-*/;

Add touch events to the canvas:
attachTouch(canvas.getElement());

Yayy.....
0

GWT Generic Event Bus

I was looking at GWT Event Bus implementation on MVP Design Pattern.I think it's good but I'm too lazy to write the event and eventhandler classes for each type of event.So I decided to wrote a helper to simplify the implementation.

May be someone is disagree with this solution.

EventBusGenericEventHandler.java
package net.vcari.webipc.client;

import com.google.gwt.event.shared.EventHandler;

public interface EventBusGenericEventHandler  extends EventHandler{
  void  onEventTrigger(EventBusGenericEvent event);
}

The event bus event handler.

EventBusGenericEvent.java
package net.vcari.webipc.client;

import java.util.List;

import com.extjs.gxt.ui.client.data.BaseModelData;
import com.extjs.gxt.ui.client.data.ModelData;
import com.google.gwt.event.shared.GwtEvent;

public class EventBusGenericEvent extends GwtEvent<EventBusGenericEventHandler>{
  public Type<EventBusGenericEventHandler> eventType;

  public ModelData dataModel;
  public List<ModelData> dataModelList;
  
  @Override
  public Type<EventBusGenericEventHandler> getAssociatedType() {
    return eventType;
  }

  @Override
  protected void dispatch(EventBusGenericEventHandler handler) {
    handler.onEventTrigger(this);    
  }

}

Event bus event. I use GXT modeldata in my application. I put extra variable for single data(ModelData) and List. I use 2 variable to avoid confusion between List and single ModelData (^&%@&YY(&@& - dirty solution. Hahahaha).


EventBusTypes.java
package net.vcari.webipc.client;

import com.google.gwt.event.shared.GwtEvent.Type;

public class EventBusTypes {
  
  /**
   * Set current location event type. Use to trigger data update for other location like in image viewer
   */
  public static Type<EventBusGenericEventHandler> setCurrentLocationEvent=new Type<EventBusGenericEventHandler>();
  
  /**
   * Set current location process updated event type
   */
  public static Type<EventBusGenericEventHandler> setCurrentLocationUpdatedEvent=new Type<EventBusGenericEventHandler>();
  
  /**
   * Set other location event type. Use to trigger data update for other location like in image viewer
   */
  public static Type<EventBusGenericEventHandler> setOtherLocationEvent=new Type<EventBusGenericEventHandler>();
  
  /**
   * Set other location process updated event type
   */
  public static Type<EventBusGenericEventHandler> setOtherLocationUpdatedEvent=new Type<EventBusGenericEventHandler>();
  
}
The registers of event types.

I  declare the event bus as static. It can be called from other class.
public static EventBus EVENT_BUS = GWT.create(SimpleEventBus.class);


To trigger the event:
EventBusGenericEvent event = new EventBusGenericEvent();
event.eventType=EventBusTypes.setCurrentLocationEvent;
event.dataModel=pagingGrid.getGrid().getSelectionModel().getSelectedItem();
Application.EVENT_BUS.fireEvent(event);
Declare the event, set the type, set the data and fire the event.

To handle the event:

I think it's easier to declare the HandlerRegistration variable in module/class scope as it can be accessed anywhere inside the module/class. This is because it's required to remove the event handler when the container (like form or panel) is closed. If not, the event handler will be handled even the container has ben closed.
HandlerRegistration onSetOtherLocationHandlerRegistration;

Put the handler (may be in onRender function).
onSetOtherLocationHandlerRegistration=Application.EVENT_BUS.addHandler(EventBusTypes.setOtherLocationUpdatedEvent, new EventBusGenericEventHandler() {

      @Override
      public void onEventTrigger(EventBusGenericEvent event) {
        onSetOtherLocationEvent(event);
      }
    });

Finally, remove the handler when the form is closed / unloaded.
@Override
  protected void onUnload() {
    super.onUnload();
    onSetOtherLocationHandlerRegistration.removeHandler();
  }

Voila !!!

0

GWT - nocache.js cached

I got a problem when my GWT site keep notifying there is no file found for deferred binding js file. After simple investigation, I realize the main nocache.js file is cached. I thought it will be cache automatically but I was wrong.

A simple solution is to make web server to send a header not to cache the nocache.js files.
I found the solution here :
http://www.askapache.com/htaccess/using-http-headers-with-htaccess.html
http://code.google.com/p/google-web-toolkit/issues/detail?id=4823

Simply modify the .htaccess file (I use this file for compression) and put the following configuration:

<filesMatch "\.(nocache.js)$">
FileETag None
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>
</filesMatch>

or this one
<Files *.nocache.*>
  ExpiresActive on
  ExpiresDefault "now"
  Header merge Cache-Control "public, max-age=0, must-revalidate"
</Files>


Voila !!!. :)


 
 
0

Disable Canvas ContextMenu in GWT

This week I'm working with canvas and I got a problem to hide the context menu from being appeared. I had try several methods such as handling the mouse up event, click event , sink events but all of them are not working.

Finally, I found a solution from 
http://svenbuschbeck.net/wordpress/2011/02/disable-context-menu-in-gwt/

The solution is similar to mouse up event but this one is using DomHandler.

Canvas canvas = Canvas.createIfSupported();
if (canvas == null) {
    return;
}

canvas.addDomHandler(new ContextMenuHandler() {

    @Override
    public void onContextMenu(ContextMenuEvent event) {
        event.preventDefault();
        event.stopPropagation();
    }
},ContextMenuEvent.getType());

0

GWT - How to show the wait cursor for long tasks




  Source : http://ui-programming.blogspot.com/2010/01/gwt-how-to-show-wait-cursor-for-long.html

GWT - How to show the wait cursor for long tasks

In case you have a task that takes more than 2 seconds you need to signal to the user that he needs to wait a little longer than usual. This can be done in many ways, here, we are talking about the setting the cursor to a WAIT cursor.

For this reason we have wrote 2 static functions to set the cursor to wait and then to put it back when the long task is over.

public static void showWaitCursor() {
    DOM.setStyleAttribute(RootPanel.getBodyElement(), "cursor", "wait");
}

public static void showDefaultCursor() {
    DOM.setStyleAttribute(RootPanel.getBodyElement(), "cursor", "default");
}

Here are the possible types of the HTML cursors, which can be used in different cases:

 


Example of how to use the functions to change HTML cursor for long task:

/**
 * create the long task instance, which in our case extends:
 *   interface Function { execute(); } 
 */
final Task longTask = new Task();

/** shows the wait cursor */
showWaitCursor();

/** launch the long task in a separate thread */
DeferredCommand.addCommand (new Command() {
    @Override
    public void execute () {
        try {
            longTask.execute();
        } finally {
            /* when task finishes (successful, or with failure) set back the default cursor */
            showDefaultCursor();
        }
    }
});

That's pretty much all.

Cheers!
0

Using GWT Event Bus

Simple tutorial on GWT Event Bus.
Tested and it works.

Source : http://stackoverflow.com/questions/6030202/how-to-use-the-gwt-eventbus

When you divide the project into logical parts (for example with MVP) than several different parts sometime need to communicate. Typical communication is sending some status changes, e.g.:
  • user logged-in / loged-out.
  • user navigated directly via URL to page so menu needs to be updated.
Event bus is quite logical to use in this cases.
To use it you instantiate one EventBus per app which is then used by all other classes. To achieve this you use static field, factory or dependency injection (GIN in case of GWT).
Example with you own event types:
 
public class AppUtils{

    public static EventBus EVENT_BUS = GWT.create(SimpleEventBus.class);
}
 
Normally you'd also create your own event types and handlers:
 
public class AuthenticationEvent extends GwtEvent<AuthenticationEventHandler> {
public static Type<AuthenticationEventHandler> TYPE = new Type<AuthenticationEventHandler>();

  @Override
public Type<AuthenticationEventHandler> getAssociatedType() {
    return TYPE;
}
@Override
protected void dispatch(AuthenticationEventHandler handler) {
    handler.onAuthenticationChanged(this);
}
}

and the handler:
 
public interface AuthenticationEventHandler extends EventHandler {
    void onAuthenticationChanged(AuthenticationEvent authenticationEvent);
}

Then you use it like this:

AppUtils.EVENT_BUS.addHandler(AuthenticationEvent.TYPE, new AuthenticationEventHandler()     {
        @Override
        public void onAuthenticationChanged(AuthenticationEvent authenticationEvent) {
            // authentication changed - do something
        }
    });

and fire the event:

AppUtils.EVENT_BUS.fireEvent(new AuthenticationEvent());


0

GXT Grid Column Alignment

How to align GXT grid column?
Answer : it can be done at ColumnConfig.
Here is sample code :

List configs = new ArrayList();

ColumnConfig column = new ColumnConfig();
column.setId("name");
column.setHeader("Company");
column.setWidth(200);
configs.add(column);

column = new ColumnConfig();
column.setId("symbol");
column.setHeader("Symbol");
column.setWidth(100);
configs.add(column);

column = new ColumnConfig();
column.setId("last");
column.setHeader("Last");
column.setAlignment(HorizontalAlignment.RIGHT);
column.setWidth(75);
column.setRenderer(gridNumber);
configs.add(column);

column = new ColumnConfig("change", "Change", 100);
column.setAlignment(HorizontalAlignment.RIGHT);
column.setRenderer(change);
configs.add(column);

The full example can be found here :
http://www.java2s.com/Code/Java/GWT/SetcolumnalignmentnameandheightExtGWT.htm
0

GWT Anchor Image Link

In my project, I need to display image link in GXT grid with the cursor changed to pointer when the cursor hover on the image. When clicked, it will open a new window.

Here is the code :

Anchor anchor =new Anchor();
final Image image = new Image("../resources/images/pdf.png");

anchor.addMouseOverHandler(new MouseOverHandler() {
    
    @Override
    public void onMouseOver(MouseOverEvent event) {
        DOM.setStyleAttribute(image.getElement(), "cursor", "pointer");
    }
});
                
anchor.addMouseOutHandler(new MouseOutHandler() {
    
    @Override
    public void onMouseOut(MouseOutEvent event) {
        DOM.setStyleAttribute(image.getElement(), "cursor", "default");                        
    }
});
anchor.addClickHandler(new ClickHandler() {
    
    @Override
    public void onClick(ClickEvent event) {
        String url="upload/" + model.get(property).toString();
        Window.open(url, "_blank", "");
        Info.display("Hardware", "Show Datasheet");
    }
});                
anchor.getElement().appendChild(image.getElement());            
return anchor;

0

GWT 2.4. Static Google Map in Frame not working

Before this static Google map can be viewed using Frame object and what I need to do is to give the URL of the static map. Please refer to my previous post http://peyotest.blogspot.com/2011/03/gwt-google-map-static-and-dynamic.html
 
Unfortunately, when I upgraded the GWT to version 2.4, it didn't display the image.
It works fine with web page but not image.
So I searched in Google, but there is no one having problem like I did.

Since the static map is an image, so I decided to use image object in GWT and it can be loaded from URL. That's nice and easy solution for me.

Here is the new code :


package com.vcari.jscadav2.client;

import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Frame;
import com.google.gwt.user.client.ui.Image;

public class SiteMapStaticMapPanel extends SiteMapPanel {

    public SiteMapStaticMapPanel(){
        super();
    }    
    
    Frame frame = new Frame("http://google.com");
    final Image image = new Image();


    @Override
    protected void onRender(Element parent, int index) {
        super.onRender(parent, index);
        //setLayout(new FitLayout());
        setBorders(false);
        image.setWidth("640");
        image.setHeight("430");
        image.setVisible(true);
        add(image);
    }
    
    /**
     * Set map center to the defined latitude and longitude
     * @param latitude
     * @param longitude
     */
    public void setMapCenter(Double latitude, Double longitude, int zoomLevel) {                
       Integer width=this.getWidth();
       Integer height=this.getHeight();
       String url="http://maps.google.com/maps/api/staticmap?center={0},{1}&zoom={2}&size={3}x{4}&maptype=roadmap&sensor=false";
       url+="&markers=color:red7C%{0},{1}";
       //url=String.format(url, latitude,longitude,zoomLevel,width,height);
       url=url.replace("{0}", latitude.toString());
       url=url.replace("{1}", longitude.toString());
       url=url.replace("{2}", String.valueOf(zoomLevel));
       url=url.replace("{3}", width.toString());
       url=url.replace("{4}", height.toString());
       url=url.replace("{5}",  Application.areaName);      
       image.setUrl(url);
    }
}
0

GXT Paging ListView

Simply bind the store to ListView and loader to PagingToolBar.
Here is the source code. You might need to refer to my previous posting on JSON reader and paging grid.

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ppktechnology.assetmanagement.client;

import java.util.List;

import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.BasePagingLoader;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelReader;
import com.extjs.gxt.ui.client.data.ListLoadResult;
import com.extjs.gxt.ui.client.data.ListLoader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.ListViewEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.util.Format;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.ListView;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
import com.extjs.gxt.ui.client.widget.toolbar.PagingToolBar;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.ppktechnology.assetmanagement.client.model.ImagesModel;
import com.vcari.client.utils.DataUtils;

/**
 * 
 * @author peyo
 */
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
public class ImagesList extends LayoutContainer {

    ListStore store = ImagesModel.getInstance().getPagingStore();
    int limit = 20;

    @Override
    protected void onRender(Element parent, int index) {
        super.onRender(parent, index);
        final ContentPanel panel = new ContentPanel();
        setLayout(new FitLayout());
        
        panel.setCollapsible(true);
        panel.setAnimCollapse(false);
        panel.setFrame(true);
        panel.setId("images-view");
        panel.setHeading("Simple ListView (0 items selected)");
        panel.setBodyBorder(false);
        panel.setLayout(new FitLayout());
                
        ListView<ModelData> view = new ListView<ModelData>() {
            @Override
            protected ModelData prepareData(ModelData model) {
                String s = model.get("imagedesc");
                model.set("imagedesc", Format.ellipse(s, 15));
                String thumbnail="images/" +  model.get("thumbnail");
                model.set("thumbnail", DataUtils.formatURL(thumbnail));
                String imagefile="images/" +  model.get("imagefile");
                model.set("imagefile", DataUtils.formatURL(imagefile));
                return model;
            }

        };

         view.addListener(Events.OnDoubleClick, new Listener<ListViewEvent<ModelData>>() {

                @Override
                public void handleEvent(ListViewEvent<ModelData> be) {
                    String imgurl = be.getModel().get("imagefile");
                    com.google.gwt.user.client.Window.open(imgurl, "_blank", "");
                }
            });
        
        final PagingToolBar pagingToolBar = new PagingToolBar(limit);
        pagingToolBar.bind((BasePagingLoader) store.getLoader());
        panel.setBottomComponent(pagingToolBar);
          
        view.setTemplate(getTemplate());
        view.setStore(store);
        view.setItemSelector("div.thumb-wrap");
        view.getSelectionModel().addListener(Events.SelectionChange, new Listener<SelectionChangedEvent<ModelData>>() {

            public void handleEvent(SelectionChangedEvent<ModelData> be) {
                panel.setHeading("Simple ListView (" + be.getSelection().size() + " items selected)");
            }

        });
        panel.add(view);
        add(panel);
        store.getLoader().load();
    }

    private native String getTemplate() /*-{
        return [ '<tpl for=".">', '<div class="thumb-wrap" id="{imageid}">',
                '<div class="thumb"><img src="{imagefile}" title="{imagedesc}"></div>',
                '<span class="x-editable">{imagedesc}</span></div>', '</tpl>',
                '<div class="x-clear"></div>' ].join("");

    }-*/;

}

0

GWT - PHP on Apache 3rd Review

Yesterday, on the GWT training session at PPK, Ilhamy (one of my internship student) told me he found another way to communicate GWT with PHP. Actually it's very simple solution without need to configure Apache.

In the solution, the project must located in /htdocs folder and compiler argument must be configured.

The original argument:

-remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -startupUrl GWTPHP.html -logLevel INFO -codeServerPort 9997 -port 8888 -war C:\xampp\htdocs\GWTPHP\war com.vcari.jscadav2.Jscadav2_gwt

New configuration

-noserver -remoteUI "${gwt_remote_ui_server_port}:${unique_id}" -startupUrl http://localhost/GwtPhp/war/GWTPHP.html -logLevel INFO -codeServerPort 9997 -war C:\xampp\htdocs\GWTPHP\war com.peyotest.gwtphp.GWTPHP


Steps :
  1. add -noserver 
  2. change startup url from GWTPHP.html to full url http://localhost/GwtPhp/war/GWTPHP.html
  3. remove server port  -codeServerPort 9997 
The full article about this can be found here:
http://cambiatablog.wordpress.com/2010/11/22/gwt-developing-with-hosted-mode-and-phpxampp/
0

GWT XMLRPC

On my previous work on XMLRPC, I had work with C# and PHP.
This morning I decide to try a library written for GWT.
The project can be found at:

http://code.google.com/p/xmlrpc-gwt/

Since there is no compiled .jar files, so I need create the .jar file myself.
Since I just used Eclipse for 2 weeks (before this using Netbeans + GWT4NB), it take me a long way just to create the .jar file. Actually to create .jar file is very simple step and require less than a minute.

Simply put the library inherits setting in the project.

<inherits name='com.fredhat.gwt.xmlrpc.XMLRPC'>

I just modify the sample given on the project's wiki and call the add function in my previous XMLRPC server sample.


XmlRpcClient client = new XmlRpcClient("http://127.0.0.1/xmlrpc/server.php");
String methodName = "add";
Object[] params = new Object[]{3, 4};
 
XmlRpcRequest<Integer> request = new XmlRpcRequest<Integer>(client, methodName, params, new AsyncCallback<Integer>() {
   public void onSuccess(Integer response) {
           // Handle integer response logic here
     Console.writeLine(response);
   }

   public void onFailure(Throwable response) {
           String failedMsg = response.getMessage();
           // Put other failed response handling logic here
           Console.writeLine(failedMsg);
   }
});
request.execute();


Done and it work just fine.
The .jar file can be found here.

GXT HighCharts

In my project, I had implement GXT chart. It works well on my system but my client wants to print the graph. Since the chart is in Flash, it can't be printed directly from the webpage. Actually I found an article to make it printable, but for it's not a good solution.

I found several project for JavaScript chart, but I to make it work with GWT & GXT is big problem for me.
Luckily, somebody has been working with Highchart (one of my candidate before) and give it a try.
I just follow the sample, and it works.

The project require jquery and highchart library.
After this I will found out whether it is work without jQuery since I can do AJAX query using GWT.

The project can found here: 
http://highcharts-gxt.sourceforge.net/wordpress/

Highchart
http://www.highcharts.com/

I'm going to replace the existing chart. Hopefully, there is no big issues arise.

0

GWT Google Map (Static and Dynamic)

In my project, my client want to use Google map.
I had put the Google Map V3 but due to poor internet connection, the retrieval time is very slow. They want to use static map.

I decide to create an option for them to choose whether to use dynamic or static Google map. To change between dynamic and static just simply change the instance.

The dynamic map, I use a library from http://code.google.com/p/gwt-google-maps-v3/

SitemapPanel.java
package com.vcari.jscadav2.client;

import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.google.gwt.user.client.Element;

public abstract class SiteMapPanel extends LayoutContainer{

    @Override
    protected void onRender(Element parent, int index) {
        super.onRender(parent, index);
    }
    
     public abstract void setMapCenter(Double latitude, Double longitude, int zoomLevel);
}



SiteMapStaticMapPanel.java (Static Map)
This solution is working for GWT 2.4. Please refer to my new post below for solution. http://peyotest.blogspot.com/2011/09/gwt-24-static-google-map-in-frame-not.html

package com.vcari.jscadav2.client;

import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Frame;

public class SiteMapStaticMapPanel extends SiteMapPanel {

    public SiteMapStaticMapPanel(){
        super();
    }    
    
    Frame frame = new Frame();

    @Override
    protected void onRender(Element parent, int index) {
        super.onRender(parent, index);
        setLayout(new FitLayout());
        setBorders(false);
        add(frame);
    }
    
    /**
     * Set map center to the defined latitude and longitude
     * @param latitude
     * @param longitude
     */
    public void setMapCenter(Double latitude, Double longitude, int zoomLevel) {                
       Integer width=this.getWidth();
       Integer height=this.getHeight();
       String url="http://maps.google.com/maps/api/staticmap?center={0},{1}&zoom={2}&size={3}x{4}&maptype=roadmap&sensor=false";
       url+="&markers=color:red7C%{0},{1}";
       url=String.format(url, latitude,longitude,zoomLevel,width,height);
       url=url.replace("{0}", latitude.toString());
       url=url.replace("{1}", longitude.toString());
       url=url.replace("{2}", String.valueOf(zoomLevel));
       url=url.replace("{3}", width.toString());
       url=url.replace("{4}", height.toString());
       url=url.replace("{5}",  Application.areaName);
      
       frame.setUrl(url);
    }
}



Dynamics Google Map Version 3

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.vcari.jscadav2.client;

import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.google.gwt.maps.client.MapOptions;
import com.google.gwt.maps.client.MapTypeId;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.base.LatLng;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.user.client.Element;

/**
 *
 * @author peyo
 */
public class SiteMapV3Panel extends SiteMapPanel {

    private Marker marker;
    private MapWidget mapWidget;

    public SiteMapV3Panel() {
        setLayout(new FitLayout());
                      
        final MapOptions options = new MapOptions();
        // Zoom level. Required
        options.setZoom(8);
        // Open a map centered on Cawker City, KS USA. Required
        options.setCenter(new LatLng(5.519216, 116.822204));
        // Map type. Required.
        options.setMapTypeId(new MapTypeId().getRoadmap());

        marker=new Marker();
        
        // Enable maps drag feature. Disabled by default.
        options.setDraggable(true);
        // Enable and add default navigation control. Disabled by default.
        options.setNavigationControl(true);
        // Enable and add map type control. Disabled by default.
        options.setMapTypeControl(true);
        mapWidget = new MapWidget(options);
        mapWidget.setSize("800px", "600px");
        add(mapWidget);
    }
    
   
    @Override
    protected void onRender(Element parent, int index) {
        super.onRender(parent, index);
    }

    /**
     * Set map center to the defined latitude and longitude
     * @param latitude
     * @param longitude
     */
    public void setMapCenter(Double latitude, Double longitude, int zoomLevel) {                
        mapWidget.getMap().setZoom(zoomLevel);
        mapWidget.getMap().panTo(new LatLng(latitude, longitude));
        marker.setPosition(new LatLng(latitude, longitude));
        marker.setMap(mapWidget.getMap());
        marker.setTitle(Application.areaName);
    }
}

0

GXT Paging Toolbar Disabled

The paging toolbar keep disabled when it loads data and a new request is made before the last request accomplished. My temporary solution is to use flag to avoid request the same data several time concurrently. But what about, the data is different ????

Finally I found the solution after read the post in GXT forum. You can find it here.
http://www.sencha.com/forum/showthread.php?85011-Loading-Store-twice-causes-PagingToolBar-to-disable

But in my solution, I just use override the loader LoadListener events. The concept is to disable paging toolbar on data load and enable it on load completed.

Code:
grid.getStore().getLoader().addLoadListener(new LoadListener() {

@Override
public void loaderBeforeLoad(LoadEvent le) {
getPanel().getBottomComponent().setEnabled(false);
}

@Override
public void loaderLoad(LoadEvent le) {
getPanel().getBottomComponent().setEnabled(true);
super.loaderLoad(le);
}
});

Hope this code is useful to you too.
0

GWT Code Splitting

In my GWT + GXT project, the obfuscated javascript output file is around 1.1MB. It takes quite long for the browser to load all the files before the system is running. So I gave a look on GWT code splitting.

It's very simple and just need to implement
  1. GWT.runAsync(new RunAsyncCallback() {}
  2. Set GWT compiler parameter : -compileReport. Make sure you disable draft compile mode since it will not produce the SOYC(Story of your compile)

You can see the compile report as you know what is going to be downloaded on initial download, full download and leftover.

http://code.google.com/webtoolkit/doc/latest/DevGuideCodeSplitting.html
http://code.google.com/webtoolkit/doc/latest/DevGuideCompileReport.html

Soon I will try to reduce the usage of the GXT library which is the most codes included in my initial download.
0

GXT Paging Grid With Remote Search

I'm using paging grid in GXT to view a list.
The basic is shown below:

ScriptTagProxy<PagingLoadResult<ModelData>> proxy = new ScriptTagProxy<PagingLoadResult<ModelData>>(url);
JsonPagingLoadResultReader<PagingLoadResult<ModelData>> reader = new JsonPagingLoadResultReader<PagingLoadResult<ModelData>>(type);
final PagingLoader<PagingLoadResult<ModelData>> loader = new BasePagingLoader<PagingLoadResult<ModelData>>(proxy, reader);
loader.setRemoteSort(true);
final ListStore<ModelData> mystore = new ListStore<ModelData>(loader);
return mystore;


But I want to use the same paging component for remote search. Finally I came out with this solution.

private void searchStaff() {
String url = "index.php?option=com_model&model={0}&action=getStaffList";
PagingLoadConfig config = new BasePagingLoadConfig();
config.setOffset(0);
config.setLimit(50);

BasePagingLoader loader = ((BasePagingLoader) store.getLoader());
ScriptTagProxy proxy = (ScriptTagProxy) loader.getProxy();
if (keyword.getValue() == null || keyword.getValue().equals("")) {
} else {
url += "&keyword=" + keyword.getValue().toString();
}
url = url.replace("{0}", "Staff");
url = DataUtils.formatURL(url);
url = url.replaceAll("kpiwebgwt", "kpiweb");
proxy.setUrl(url);
store.getLoader().load(config);
}
 
Copyright © peyotest