Showing posts with label gwt. Show all posts
Showing posts with label gwt. Show all posts

Thursday, December 6, 2012

The Future of GWT–Report

I just read the report about the future of GWT, really good job done by the GWT Steering Committee. You can get your free copy from the report here:

https://vaadin.com/gwt/report-2012

I was actually surprised that there are not a lot of organizations using GWT for building portlets. I personally know several and I was involved to develop GWT Portlets few times as well. I suppose that most of this organizations did not post to the survey or they just select business applications instead of portlets, which I can understand. The portlets are mostly applications for the business side in the organizations. Your usually never sell internally in the organization portlets but business application and the business does not really care what it calls, they want to have the functionality they require and pay.

Later the Committee will post the wish list here:

https://vaadin.com/gwt/report-2012

but I think I can guess that the compiler optimization will be on the first place.

cheers,

Thursday, November 1, 2012

Create GWT Project with Spring Roo and Mongo DB using STS – Part 2

Now I will go through the next step and show you how to create the Mongo DB entities. To read the FIRST PART click HERE, to see how to create the project using Spring Roo and STS.

After you create the project you should see something like this:

image

Using the keyword “hint” in the Roo Shell allows you to see what is the next step. This is really very easy step by step wizard way to work. In my case I will go for the following Roo Command:

mongo setup

which setups the project to use Mongo DB. Inside your Roo Shell you should see something like this:

image

After you create the project you may get some errors like this one:

Description    Resource    Path    Location    Type
Referenced file contains errors (http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd). For more information, right click on the message in the Problems View and select "Show Details..." applicationContext-mongo.xml /ofers/src/main/resources/META-INF/spring line 1 XML Problem


To fix this click on the project with right mouse button and then from Maven select Update Project, like this:


image


This now should update your project and download the needed libraries. After that the error message will disappear.


Next major step is to create the entities. For that reason I create very simple tables, which I will use as domains entities into my project. This is the example.


image


Just for info, the ID in my table is not something you have to create, the Mongo DB database creates this automatically for every entry in the table. Also what is important to know is the “Reference” means you have Many to One relationship and “Set” means One to Many.


To create the entities using Roo you have to type following lines using the Roo Shell:


For PersonType table:

entity mongo --class ~.domain.PersonType --testAutomatically
field string --fieldName type --sizeMin 128 --notNull



For Person table:

entity mongo --class ~.domain.Person --testAutomatically
field string --fieldName title --sizeMin 16 --notNull
field string --fieldName firstname --sizeMin 128 --notNull
field string --fieldName lastname --sizeMin 128 --notNull
field string --fieldName street --sizeMin 256 --notNull
field number --fieldName plz --type java.lang.Integer
field string --fieldName city --sizeMin 128 --notNull
field string --fieldName email --sizeMin 256 --notNull
field number --fieldName dataofbirth --type java.lang.Integer
field string --fieldName pwd --sizeMin 128 --notNull
field reference --fieldName type --type ~.domain.PersonType



For the layer support:


 

repository mongo --interface ~.repository.PersonTypeRepository --entity ~.domain.PersonType
repository mongo --interface ~.repository.PersonRepository --entity ~.domain.Person

service --interface ~.service.PersonTypeService --entity ~.domain.PersonType
service --interface ~.service.PersonService --entity ~.domain.Person



 


Now you have the Mongo DB entities and you can proceed with the next step (Part 3) of this tutorial, which I will post very soon and which will show how to setup the GWT project.

Wednesday, October 31, 2012

Create GWT Project with Spring Roo and Mongo DB using STS – Part 1

I started to work on private project where I used Spring Roo to create the GWT Project. The project also should use the Mongo DB. As IDE I use the Spring Tool Suite (STS). So here as usual my cookbook style tutorial.

First of all you have to create Spring Roo Project. As I mention I used STS so everything is integrated inside. another possibility could be to create the project just directly using Spring Roo in command line mode.  

image

Select to create Spring Roo project, new Roo Project creation Window opens, as shown bellow:

image

In the next screen type the name of the project and then the namespace. Also from the build-in provider I select as packaging method WAR. You can change this later if you which.

image

Next screen is not really something special, as shown above, just click on Finish to proceed with the project creation.

image

After you clicked on Finish button the STS creates the project for you and opens the Roo Shell automatically.

Here I am experience sometimes problems which I cannot reproduce but for some reason the tool does not create the project well and shows error messages. Basically the problem is that it does not create the Resources folder. In this case I just delete the project and create it again.

This is the first part of my tutorial and the simplest one. In the next part I will show you how to setup the Mongo DB and the entities and then how to setup the project as GWT one.

Tuesday, May 29, 2012

Using LayoutPanel without RootLayoutPanel

This one is simple but could cause you some headaches when you try to test some components like DataGrid. Basically the DataGrid needs to be used inside some GWT Layout Panel like for example LayoutPanel or DockLayoutPanel and so on, which also requires the use of RootLayoutPanel. There are of course cases where you are not able to use the RootLayoutPanel but the RootPanel. You may wonder that nothing is shown on the screen, when you try this. To fix this you need to se the panel size explicitly, otherwise the panel is there but does not expand to show the content inside. For example in my case:

DataGrid<Contact> table = new DataGrid<Contact>();
LayoutPanel panel = new LayoutPanel();
panel.setSize("30em", "10em");
panel.add(table);
RootPanel.get("yourId").add(panel);



Very easy but don’t forget it!

Saturday, April 7, 2012

Native GWT Drag and Drop

I just add some new examples, which I am going to describe in the next days, one of them is the native GWT drag and drop. Now this is the very basic one example which was introduced last year on the Google I/O conference. I will use this example to extend it later and show how to do drag and drop also on custom GWT widgets without to use third party libraries. You can find the source code as usual into my example project gwt2go here. The direct links are here and here.

Just short overview of the example. Basically you will have element which you want to be able to drag and drop onto another element which will be the target. To allow element to be dragged you have to use addDragStartHandler. To do so follow this code:

final Label label = new Label("Drag me");
label.getElement().setDraggable(Element.DRAGGABLE_TRUE);
 
label.addDragStartHandler(new DragStartHandler() {
 
    @Override
    public void onDragStart(DragStartEvent event) {
        // required
        event.setData("text", "Hello World");
 
        // optinal: show copy of the image
        event.getDataTransfer()
                .setDragImage(label.getElement(), 10, 10);
    }
});

Now as mention into the conference, some widgets do not implement this interfaces so you have to go for little bit different approach using addDomHandler like this:



label.addDomHandler(new DragStartHandler() {
    @Override
    public void onDragStart(DragStartEvent event) {
        // required
        event.setData("text", "Hello World again;)");
        
        // optional
        event.getDataTransfer().setDragImage(label.getElement(), 10, 10);
    }
}, DragStartEvent.getType());

Using setData, you use a key value function which allows you to put the data to be transferred to target elements. In my case the key is ‘text’ and the value ‘Hello World’. You can use the key ‘text’ from the target element to read the value into it.


Also using setDragImage allows you to put a image or element which will be shown when you drag your element.


Now for the target element you have to go for the following code:



final Label target = new Label("Drag onto me");
// required: you must add dragoverhandler to create a target
target.addDragOverHandler(new DragOverHandler() {
    @Override
    public void onDragOver(DragOverEvent event) {
        target.getElement().getStyle().setBackgroundColor("#ffa");
    }
});
 
// add drop hanlder
target.addDropHandler(new DropHandler() {
    @Override
    public void onDrop(DropEvent event) {
        // prevent the native text drop
        event.preventDefault();
 
        // get the data out of the event
        String data = event.getData("text");
        target.setText(data);
    }
});

Two important thinks to learn here, the onDragOver allows you to set up what should happen to the element when the dragged element is over the target. Drag over is really MUST. The implementation could be empty put you have to initiate the function, otherwise your target may not work into all browsers.


The second thing is to implement addDropHandler, where you can get the transported value and use it into the target widget.


Here the links again: the MVP View here and the Panel with the Dnd example here.


chears

Wednesday, February 1, 2012

Three steps to tree view

This time something easy:). I was preparing new navigation using the GWT TreeView widget and as usual I wanted to share some of my experience with you. Basically everything works just by design, so here the three steps of creation.

First step: you have to create your cell tree model. This is in my case just the class with the name of the node and his sub nodes. I call the class CellTreeDAOModel.

 
import java.util.ArrayList;
import java.util.List;
 
public class CellTreeDAOModel {
 
    private final String name;
    private final List<String> sublevels = new ArrayList<String>();
 
    public CellTreeDAOModel(String name) {
        this.name = name;
    }
 
    public void addSubLevels(String name) {
        sublevels.add(name);
    }
 
    public String getName() {
        return name;
    }
 
    public List<String> getSubLevels() {
        return sublevels;
    }
}

Second step: create your cell tree composer. The composer contains your cell tree mode. In my case this is the CellTreeModelComposer.



import java.util.ArrayList;
import java.util.List;
 
public class CellTreeModelComposer {
 
    private final String name;
    private final List<CellTreeDAOModel> sublists = new ArrayList<CellTreeDAOModel>();
 
    public CellTreeModelComposer(String name) {
        this.name = name;
    }
 
    public CellTreeDAOModel addPlaylist(CellTreeDAOModel playlist) {
        sublists.add(playlist);
        return playlist;
    }
 
    public String getName() {
        return name;
    }
 
    public List<CellTreeDAOModel> getSubLists() {
        return sublists;
    }
}

Third step: create your tree view mode. Here you set up the nodes and define how all those nodes has be rendered:



import java.util.ArrayList;
import java.util.List;
 
import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.gwt.view.client.TreeViewModel;
 
public class CustomTreeModel implements TreeViewModel {
 
    private final List<CellTreeModelComposer> composers;
 
    /**
     * This selection model is shared across all leaf nodes. A selection model
     * can also be shared across all nodes in the tree, or each set of child
     * nodes can have its own instance. This gives you flexibility to determine
     * how nodes are selected.
     */
    private final SingleSelectionModel<String> selectionModel = new SingleSelectionModel<String>();
 
    public CustomTreeModel() {
        composers = new ArrayList<CellTreeModelComposer>();
 
        // Add compositions
        {
            CellTreeModelComposer level1 = new CellTreeModelComposer("Level 1");
            composers.add(level1);
 
            CellTreeDAOModel sublevel_1_1 = level1
                    .addPlaylist(new CellTreeDAOModel("Sub Level 1.1"));
            sublevel_1_1.addSubLevels("Level 1.1.1");
            sublevel_1_1.addSubLevels("Level 1.1.2");
            sublevel_1_1.addSubLevels("Level 1.1.3");
            sublevel_1_1.addSubLevels("Level 1.1.4");
            sublevel_1_1.addSubLevels("Level 1.1.5");
 
            CellTreeDAOModel sublevel_1_2 = level1
                    .addPlaylist(new CellTreeDAOModel("Sub Level 1.2"));
            sublevel_1_2.addSubLevels("Level 1.2.1");
            sublevel_1_2.addSubLevels("Level 1.2.2");
            sublevel_1_2.addSubLevels("Level 1.2.3");
 
            CellTreeDAOModel sublevel_1_3 = level1
                    .addPlaylist(new CellTreeDAOModel("Sub Level 1.3"));
            sublevel_1_3.addSubLevels("Level 1.3.4");
            sublevel_1_3.addSubLevels("Level 1.3.5");
 
            CellTreeDAOModel sublevel_1_4 = level1
                    .addPlaylist(new CellTreeDAOModel("Sub Level 1.4"));
            sublevel_1_4.addSubLevels("Level 1.4.1");
            sublevel_1_4.addSubLevels("Level 1.4.2");
            sublevel_1_4.addSubLevels("Level 1.4.3");
            sublevel_1_4.addSubLevels("Level 1.4.4");
            sublevel_1_4.addSubLevels("Level 1.4.5");
            sublevel_1_4.addSubLevels("Level 1.4.6");
        }
 
        // Add compositions
        {
            CellTreeModelComposer level_2 = new CellTreeModelComposer("Level 2");
            composers.add(level_2);
            CellTreeDAOModel sublevel_2_1 = level_2
                    .addPlaylist(new CellTreeDAOModel("Sub Level 2_1"));
            sublevel_2_1.addSubLevels("Level 2_1_1");
            sublevel_2_1.addSubLevels("Level 2_1_2");
            sublevel_2_1.addSubLevels("Level 2_1_3");
            sublevel_2_1.addSubLevels("Level 2_1_4");
 
            CellTreeDAOModel sublevel_2_2 = level_2
                    .addPlaylist(new CellTreeDAOModel("Sub Level 2_2"));
            sublevel_2_2.addSubLevels("Level 2_2");
            sublevel_2_2.addSubLevels("Level 2_2");
            sublevel_2_2.addSubLevels("Level 2_2");
            sublevel_2_2.addSubLevels("Level 2_2");
 
            CellTreeDAOModel sublevel_2_3 = level_2
                    .addPlaylist(new CellTreeDAOModel("Sub Level 2_3"));
            sublevel_2_3.addSubLevels("Level 2_3_1");
            sublevel_2_3.addSubLevels("Level 2_3_2");
 
            CellTreeDAOModel sublevel_2_4 = level_2
                    .addPlaylist(new CellTreeDAOModel("Sub Level 2_4"));
            sublevel_2_4.addSubLevels("Level 2_4_1");
            sublevel_2_4.addSubLevels("Level 2_4_2");
            sublevel_2_4.addSubLevels("Level 2_4_3");
            sublevel_2_4.addSubLevels("Level 2_4_4r");
        }
 
        // Add compositions
        {
            CellTreeModelComposer sublevel_3 = new CellTreeModelComposer(
                    "Level 3");
            composers.add(sublevel_3);
            CellTreeDAOModel sublevel_3_1 = sublevel_3
                    .addPlaylist(new CellTreeDAOModel("Sub Level 3_1"));
            sublevel_3_1.addSubLevels("Sub Level 3_1_1");
            sublevel_3_1.addSubLevels("Sub Level 3_1_2");
            sublevel_3_1.addSubLevels("Sub Level 3_1_3");
            sublevel_3_1.addSubLevels("Sub Level 3_1_4");
            sublevel_3_1.addSubLevels("Sub Level 3_1_5");
        }
    }
 
    @Override
    public <T> NodeInfo<?> getNodeInfo(T value) {
        if (value == null) {
            // Create a data provider that contains the list of composers
            ListDataProvider<CellTreeModelComposer> dataProvider = new ListDataProvider<CellTreeModelComposer>(
                    composers);
 
            // Create a cell to display
            Cell<CellTreeModelComposer> cell = new AbstractCell<CellTreeModelComposer>() {
                @Override
                public void render(Context context,
                        CellTreeModelComposer value, SafeHtmlBuilder sb) {
                    if (value != null) {
                        sb.appendEscaped(value.getName());
                    }
                }
            };
 
            // Return a node info that pairs the data provider and the cell
            return new DefaultNodeInfo<CellTreeModelComposer>(dataProvider,
                    cell);
 
        } else if (value instanceof CellTreeModelComposer) {
            // get the first sub level
            ListDataProvider<CellTreeDAOModel> dataProvider = new ListDataProvider<CellTreeDAOModel>(
                    ((CellTreeModelComposer) value).getSubLists());
            Cell<CellTreeDAOModel> cell = new AbstractCell<CellTreeDAOModel>() {
                @Override
                public void render(Context context, CellTreeDAOModel value,
                        SafeHtmlBuilder sb) {
                    if (value != null) {
                        sb.appendEscaped(value.getName());
                    }
                }
            };
 
            return new DefaultNodeInfo<CellTreeDAOModel>(dataProvider, cell);
 
        } else if (value instanceof CellTreeDAOModel) {
            // get the third sub level
            ListDataProvider<String> dataProvider = new ListDataProvider<String>(
                    ((CellTreeDAOModel) value).getSubLevels());
 
            // Use the shared selection model
            return new DefaultNodeInfo<String>(dataProvider, new TextCell(),
                    selectionModel, null);
        }
 
        return null;
    }
 
    @Override
    public boolean isLeaf(Object value) {
 
        if (value instanceof String) {
            return true;
        }
        return false;
 
    }
 
}

The function getNodeInfo from the TreeViewModel interface is the most important. You define into it how your tree will render the content.


If you want to use now together with UiBinding you have to define your UiField with the property provided set to true like this:



@UiField(provided = true)
CellTree cellTree;

and then inside your constructor you can use this:



// add the new tree
cellTree = new CellTree(model, null);
cellTree.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
 
//
TreeNode rootNode = cellTree.getRootTreeNode();
TreeNode firstPlaylist = rootNode.setChildOpen(0, true);
firstPlaylist.setChildOpen(0, true);

Don’t forget to put also the tree declaration inside your UiBinder 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" 
        xmlns:p1="urn:import:com.google.gwt.user.cellview.client">
    <ui:style>
        .important {
            font-weight: bold;
        }
    </ui:style>
    <g:HTMLPanel>
        <g:VerticalPanel>
            <p1:CellTree ui:field="cellTree"/>
        </g:VerticalPanel>
    </g:HTMLPanel>
</ui:UiBinder> 
cheers