views:

8779

answers:

5

I just start learning GWT and wondering how do i make different HTML pages in my GWT application. For example i want to create application for a book store. In this application I'll have three pages: 1) Home pages where i will welcome user and offer him books 2) Page to browse books by categories and view details (use GWT widgets) 3) Check out books online. Of course there could be other pages like user's details, add new book, etc. So, what is the best way of making different pages in GWT and how can i make navigation from page to page? Are there any examples, tutorials? Or do i even need to create different pages when i can create whole application in one page? Thanks

+3  A: 

If you want it to be FULL AJAXified (like a desktop app) of course you'd only need one page. Then just change the contents of the body depending on the link.

Also, there is a google group for GWT that is very very active, and I know this has been asked before there, you just need to use the "search" feature.

mives
i think by page, the asker meant how to translate the concept of traditional "page" of a web app, into the world of GWT, where you really only have one html file/page. The answer isnt really answering anything at all, given the misinterpretation of the question.
Chii
+6  A: 
Chris Boesing
+19  A: 

What I usually do in situations like this is design the webpage framework first. I'll have a div for the header, side menu and footer. I'll also have a div in my html for the main content.

Example:

<html xmlns="http://www.w3.org/1999/xhtml"&gt;
    <head>
        <meta name='gwt:module' content='org.project.package.Core=org.project.package.Core'>
    </head>
    <body>
        <!-- load the javascript for gwt -->
        <script language="javascript" src="ui/org.project.package.ui.Core.nocache.js"></script>

        <!-- for some unknown reason in IE you have to have cellpadding/spacing ON THE ELEMENT and not on the STYLE if it is in the body tag like this -->
        <table id="wrapper" cellpadding="0" cellspacing="0" style="width: 100%;height: 100%;">

      <!-- header row -->
      <tr style="height: 25%;">
       <td colspan="2" id="header"></td>
      </tr>

      <!-- body row and left nav row -->
      <tr style="height: 65%;">
       <td id="leftnav"></td>
       <td id="content"></td>
      </tr>

      <!-- footer row -->
      <tr style="height: 10%;">
       <td colspan="2" id="header"></td>    
      </tr>

        </table>

        <!-- this iframe handles history -->
        <iframe id="__gwt_historyFrame" style="width:0;height:0;border:0"></iframe>
    </body>
</html>

(If you like <div> based layouts, feel free to use those instead.)

Then you build your entry point (in my case Core.java) as you normally would, setting each of the elements as need be.

RootPanel header = RootPanel.get("header").add(new Header());
RootPanel leftNav = RootPanel.get("leftnav").add(new NavigationMenu());
RootPanel footer = RootPanel.get("footer").add(new Footer());

It is, of course, possible to have a static footer and header, but thats neither here nor there.

I also have an abstract class called "Content". Content objects extend "Composite" and will have various methods for simplifying the creation and layout of a new page. Every page that I build for this application, be it a help screen, search screen, shopping cart, or anything else, is of type Content.

Now, what I do is create a class called "ContentContainer". This is a singleton that is responsible for managing the "content" element. It has one method "setContent" that accepts objects of type "Content". It then basically removes anything within the "content" <td> and replaces it with whatever widget (Composite) you assign via the "setContent" method. The setContent method also handles history and title bar management. Basically the ContentContainer serves to aggregate all the various points of binding that you might have to make if each page content had to "know" about all the functions it must perform.

Finally, you need a way to get to that page, right? Thats simple:

ContentContainer.getInstance().setContent(new Search());

Put the above in an on-click event somewhere and you're golden.

The only things that your other widgets need to be bound to is the ContentContainer and the type of Content that they are adding.

The downsides that I can see to ChrisBo's approach are that you've got a list that has to be maintained of tokens -> pages. The other downside I can see is that I don't see how you can have an actual history system with this method.

One thing it does offer over my approach is that all page choices are pretty centralized. I'd use some sort of Enum or at least a static class with String values to prevent myself from mongling up links.

In either case, I think the point can be summed up as this: swap the content of some central page element based on what your user clicks actions your user(s) perform.

angryundead
wow, really great answers. Does the line "I don't see how you can have an actual history system with this method" refer to my method? because it has a history system, not a good on, but it has one.
Chris Boesing
Yes. I don't see how a "where I've been" history system in combination with named identifiers for new pages. Your solution is more like an abuse of what the history system is made to do. I guess though if you used the back button you'd go back to where you were last.It wasn't a jab or anything at your solution though.
angryundead
That should read: "I don't see how a 'where I've been' history system **can work** in combination with named identifiers for new pages"
angryundead
Hey thanks a lot this helps !!
Anand
A: 

Add a module for each page you have that needs the GWT functionality. Reuse your components. http://codeherding.blogspot.com

Luis Mesa
+1  A: 

GWT Multipage - simple framework for multi-page-GWT-applications.

Helpa