it-swarm.com.de

Tutorial zu mehreren Seiten in Google Web Toolkit (GWT)

Ich habe gerade angefangen zu lernen Google Web Toolkit (GWT). Wie erstelle ich verschiedene HTML-Seiten in meiner GWT-Anwendung?

Ich möchte zum Beispiel eine Anwendung für eine Buchhandlung erstellen. In dieser Anwendung habe ich drei Seiten: 

  1. Startseite, auf der ich den Benutzer begrüße und die Benutzerbücher anbiete 
  2. Seite zum Durchsuchen von Büchern nach Kategorien und Anzeigen von Details (Verwenden von GWT-Widgets) 
  3. Schauen Sie sich Bücher online an.

Natürlich könnte es auch andere Seiten geben, z. B. Angaben zum Benutzer, neues Buch hinzufügen usw. Was ist der beste Weg, um verschiedene Seiten in GWT zu erstellen, und wie kann ich von Seite zu Seite navigieren? Gibt es Beispiele oder Tutorials? Oder muss ich sogar andere Seiten erstellen, wenn ich eine gesamte Anwendung auf einer Seite erstellen kann?

60
Maksim

Was ich normalerweise in solchen Situationen mache, ist das Design des Webseiten-Frameworks. Ich habe ein div für die Kopfzeile, das Seitenmenü und die Fußzeile. Ich habe auch eine div in meinem HTML für den Hauptinhalt.

Beispiel:

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

        <!-- For some unknown reason in Internet Explorer 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="footer"></td>
             </tr>

        </table>

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

(Wenn Sie <div> -basierte Layouts mögen, können Sie stattdessen diese verwenden.)

Dann erstellen Sie Ihren Einstiegspunkt (in meinem Fall Core.Java) wie gewohnt und setzen jedes Element nach Bedarf.

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

Es ist natürlich möglich, eine statische Fußzeile und Kopfzeile zu verwenden, aber das ist weder hier noch dort.

Ich habe auch eine abstrakte Klasse namens "Content". Inhaltsobjekte erweitern "Composite" und verfügen über verschiedene Methoden, um die Erstellung und das Layout einer neuen Seite zu vereinfachen. Jede Seite, die ich für diese Anwendung baue, sei es ein Hilfebildschirm, ein Suchbildschirm, ein Einkaufswagen oder etwas anderes, ist vom Typ Content.

Was ich jetzt mache, ist eine Klasse namens "ContentContainer". Dies ist ein Singleton, der für die Verwaltung des "content" -Elements verantwortlich ist. Es gibt eine Methode "setContent", die Objekte des Typs "Content" akzeptiert. Im Wesentlichen wird dann alles aus dem "content" <td> entfernt und durch das Widget (Composite) ersetzt, das Sie mit der Methode "setContent" zuweisen. Die setContent-Methode behandelt auch die Verlaufs- und Titelleistenverwaltung. Grundsätzlich dient der ContentContainer dazu, alle verschiedenen Bindungspunkte zusammenzufassen, die Sie möglicherweise festlegen müssen, wenn jeder Seiteninhalt alle Funktionen kennen muss, die er ausführen muss.

Schließlich brauchen Sie einen Weg, um zu dieser Seite zu gelangen, richtig? Das ist einfach:

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

Setzen Sie das Obige irgendwo in ein Ereignis, und Sie sind begeistert.

Die einzigen Dinge, an die Ihre anderen Widgets gebunden werden müssen, sind der ContentContainer und der Inhaltstyp, den sie hinzufügen.

Der Nachteil von ChrisBos Ansatz ist, dass Sie eine Liste mit Token -> Seiten haben. Der andere Nachteil, den ich sehen kann, ist, dass ich nicht sehe, wie Sie mit dieser Methode ein tatsächliches Historiesystem haben können.

Eine Sache, die es über meinen Ansatz bietet, ist, dass alle Seitenauswahlmöglichkeiten ziemlich zentral sind. Ich würde eine Art Enum oder zumindest eine statische Klasse mit String-Werten verwenden, um mich daran zu hindern, Links aufzumischen.

In beiden Fällen denke ich, dass der Punkt folgendermaßen zusammengefasst werden kann: Vertauschen Sie den Inhalt einiger zentraler Seitenelemente auf was Ihr Benutzer klickt Aktionen, die von Ihren Benutzern ausgeführt werden.

74
Chris Ruffalo

Ich würde die HyperLink- und History-Klasse verwenden. Das Gute an der Hyperlink-Klasse ist, dass sie dieses Token setzt (z. B. # foobar) und alles was Sie tun müssen, ist das Ereignis abzufangen, das ausgelöst wird, wenn der Wert des Token geändert wird (ValueChangeEvent). Im eventHandler würden Sie dann die Seiten ersetzen.

Beispiel: Adresse der Begrüßungsseite: www.yourpage.com/#homeauf dieser Seite wäre ein Link zur "Buchsuche" -Seite. Wenn der Link angeklickt wird, wäre die neue Adresse ungefähr so : www.yourpage.com/#browse

Und hier ist der Code:


public class MainEntryPoint implements EntryPoint, ValueChangeHandler {
    VerticalPanel panel = new VerticalPanel();
    Label label=new Label();
    public void onModuleLoad() {
        Hyperlink link1 = new Hyperlink("books", "browse");
        Hyperlink link2 = new Hyperlink("user details", "details");
        panel.add(link1);
        panel.add(link2);
        panel.add(label);
        RootPanel.get().add(panel);
        History.addValueChangeHandler(this);
        //when there is no token, the "home" token is set else changePage() is called.
        //this is useful if a user has bookmarked a site other than the homepage.
        if(History.getToken().isEmpty()){
            History.newItem("home");
        } else {
            changePage(History.getToken());
        }
    }

public void onValueChange(ValueChangeEvent event) {
    changePage(History.getToken());
}
public void changePage(String token) {
    if(History.getToken().equals("browse")) {
        label.setText("Here would be some books");
    } else if (History.getToken().equals("details")) {
        label.setText("Here would be the user details");
    } else {
        label.setText("Welcome page");
    }
}

} </ pre> </ code>

20
Chris Boesing

Genial! Ich kombinierte die Antwort von Chris R. mit Chris Boesing, um Folgendes zu finden:

Dies ist die Startseite des Index

public class Index implements EntryPoint, ValueChangeHandler<String> {
    public void onModuleLoad() {
        History.addValueChangeHandler(this);
        if (History.getToken().isEmpty()) History.newItem("index");
        Composite c = new Login(); 
        FlowControl.go(c);
    }

    public void onValueChange(ValueChangeEvent<String> e) {
        FlowControl.go(History.getToken());
    }
}

Dies ist der Controller oder ContentContainer nach Chris R.

public class FlowControl {
private static FlowControl instance;
private FlowControl() {}
public static void go(Composite c) {
    if (instance == null) instance = new FlowControl(); // not sure why we need this yet since everything is static.
    RootPanel.get("application").clear();
    RootPanel.get("application").getElement().getStyle().setPosition(Position.RELATIVE); // not sure why, but GWT throws an exception without this. Adding to CSS doesn't work.
    // add, determine height/width, center, then move. height/width are unknown until added to document. Catch-22!
    RootPanel.get("application").add(c);
    int left = Window.getClientWidth() / 2 - c.getOffsetWidth() / 2; // find center
    int top = Window.getClientHeight() / 2 - c.getOffsetHeight() / 2;
    RootPanel.get("application").setWidgetPosition(c, left, top);
    History.newItem(c.getTitle()); // TODO: need to change and implement (or override) this method on each screen
}

public static void go(String token) {
    if (token == null) go(new Login());
    if (token.equals("cart")) go(new Cart());
    if (token.equals("login")) go(new Login());
    // Can probably make these constants in this class
}

Dann können Sie überall in Ihrem Code Hyperlinks und Schaltflächen pflegen. (Ich habe noch keine Hyperlinks ausprobiert.)

    Button submit = new Button("Submit");
    submit.addClickHandler(new ClickHandler() {
        public void onClick(ClickEvent event) {
            FlowControl.go(new MyScreen());             
        }           
    });

Ich habe meinem HTML ein div hinzugefügt

<!-- This is where the application will reside within. It is controlled by FlowControl class. -->
<div id="application"></div>

Und jetzt müssen alle Bildschirme initWidget () im Konstruktor aufrufen, anstatt RootPanel hinzuzufügen, da es sich jetzt um eine Composite-Klasse handelt

    initWidget(myPanel); // all composites must call this in constructor
9
Chloe S.

Wenn Sie möchten, dass es vollständig AJAXifiziert ist (wie eine Desktop-App), benötigen Sie natürlich nur eine Seite. Dann ändern Sie einfach den Inhalt des body abhängig vom Link. 

Es gibt auch eine google-Gruppe für GWT, die sehr aktiv ist, und ich weiß, dass dies schon vorher gefragt wurde. Sie müssen nur die "Suche" -Funktion verwenden.

5
putolaruan

GWT Multipage - einfaches Framework für mehrseitige GWT-Anwendungen.

1
Helpa

Ich habe die Antwort von Chloe S. verwendet (die Antwort von Chris R. mit der von Chris Boesing), um diesen App Controller für eine funktionierende GWT-Web-App zu erstellen. Die Version in der Produktion wird getestet (und funktioniert% 100), aber die unten beschriebene überarbeitete Version muss geändert werden, um sie mit Ihrer eigenen App zu integrieren.

AppController.Java:

/**
 * This App Controller utilizes two static inner-classes (Pages and External) 
 * to manage and server multiple pages with multiple sub-page (through their presenters) 
 * via String key constants which also serve as the literal text for the menu items.
 * 
 * Pages are added as menu commands in their respective views:
 *  // Add menu items to the menu with commands:
 *  menuItems.put(Pages.PAGE1, mainMenu.addItem(Pages.PAGE1, new Command() {
 *      public void execute() {
 *          History.newItem(Pages.PAGE1);
 *      }
 *  }));
 * 
 * Pages are fired as History tokens (from entry point Java class):
 * 
 *   **
 *   * Receives history events and pushes them to the AppController using a deferred command.
 *   * Changes the cursor to show waiting.
 *   * @param the value change token
 *   *
 *  public void onValueChange(ValueChangeEvent<String> e) {
 *      // check token to cover first historical "back" navigation:
 *      if(!History.getToken().isEmpty()) {
 *          AppController.waitCursor.execute(); // cursor is reset in page attach method
 *      }
 *      Scheduler.get().scheduleDeferred(new ScheduledCommand() {
 *          public void execute() {
 *              AppController.go(History.getToken());
 *          }
 *      });
 *  }
 *  
 * Wait cursors are implemented as CSS:
 *
 *  body.wait, body.wait * {
 *      cursor: wait !important;   
 *  }
 * 
 * NOTE: This page swapping implementation technique (based on the StackOverflow solution 
 * found here: [http://stackoverflow.com/questions/1061705/multiple-pages-tutorial-in-google-web-toolkit-gwt][1]) 
 * differs from the obtuse and ancient 2010 GWT framework documentation in that the App Controller manages / handles 
 * adding the widget to the container, and therefore all the Presenters must implement the 
 * "AppControlPresenter" or "AppControlContainerPresenter" interface to give it access to their containers.
 * (thus eliminating "public void go(final HasWidgets container);" method in all presenter architecture except for 'MainAppPresenter')
 * There is also no event bus; static method calls are used for any needed interactivity.
 *
 * Includes a popup for pages still under construction.
 */

package com.;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import Java.util.HashMap;
import Java.util.Map;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.logical.shared.AttachEvent;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DecoratedPopupPanel;
import com.google.gwt.user.client.ui.Frame;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.LayoutPanel;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.UIObject;

/**
 * 
 */
public class AppController {
    /** */
    public final static String DEFAULT_INITIAL_PAGE1_SUB_PAGE = Pages.PAGE_1A;
    /** Singleton instance for the AppController */
    private static AppController instance = new AppController();
    /** Presenter for the main app */
    private static MainAppPresenter mainAppPresenter;
    /** container for the different views */
    private static LayoutPanel container;
    /** sub-container for the different sub-views */
    private static LayoutPanel page1Container;
    /** */
    private static DecoratedPopupPanel popup;
    /** constant for Style-Dependent names for menu items (see menu-style.css) */
    public final static String MENU_ACTIVE_STYLE = "active";
    /** constant for Style-Dependent class name in css */
    public final static String CURSOR_WAIT_CLASS = "wait";  
    /** */
    public final static String POPUP_DEMO_ID = "popupDemo";
    /** */  
    public final static int DEMOP_POPUP_VERTICAL_OFFSET = 0;
    /** */
    public final static String POPUP_DEMO_STATEMENT = "<span class='text'>This page is under construction</span>"
                                                    + "<span class='char'>&hellip;</span>";
    /** */
    public static ScheduledCommand waitCursor = new ScheduledCommand() {
        @Override
        public void execute() { 
            AppController.waitCursor(true); 
        }
    };

    /** */
    public static ScheduledCommand normalCursor = new ScheduledCommand() {
        @Override
        public void execute() { 
            AppController.waitCursor(false); 
        }
    };

    /** Flag for determining if the page was reloaded */
    private static boolean reloaded = false;

    private static final LoginServiceAsync loginRpcService = GWT.create(LoginService.class);

    /**
     * Called on the resize event to set the position of the demo popup
     * window to be adjusted to the correct dimensions (size and positoin)
     * regardless of screen size.
     */
    private static ScheduledCommand resetPopupDimensions = new ScheduledCommand() {
        @Override
        public void execute() {
            if(!UNDER_CONSTRUCTION || popup == null) {
                return;
            }
            int demoWidth = Math.round(Window.getClientWidth() / MainApp.PHI),
                demoYPosition = Window.getClientHeight() / 2 - Math.round(popup.getOffsetHeight() / 2);
            popup.setWidth(String.valueOf(demoWidth) + "px");
            if(popup.getOffsetWidth() >= Window.getClientWidth()) {
                popup.setWidth("100%");
                popup.setPopupPosition(0, demoYPosition);
            } else {
                popup.setPopupPosition(Window.getClientWidth() / 2 - (popup.getOffsetWidth() / 2), demoYPosition);
            }
        }
    };

    /** */
    private static final String LOGIN_OBJECT_NAME = "Login Presenter Object";

    /**
     * static inner-class for external websites 
     */
    public static class External {
        /** The frame to contain the website */
        private static Frame frame;
        /**  */
        public static final String EXTERNAL_URL_1 = "http://";
        /**  */
        public static final String EXTERNAL_URL_2 = "http://";

        /**
         * @returns true if the name of the token is equal to one of the URLs
         * @param token the name to check
         */
        public static boolean has(String token) {
            return token.equalsIgnoreCase(EXTERNAL_URL_1)      ||
                   token.equalsIgnoreCase(EXTERNAL_URL_2);
        }

        /**
         * Gets the external Frame object
         * @param url
         * @return Frame
         */
        public static Frame get(String url) {
            if(frame == null) {
                frame = new Frame(url);
                frame.addAttachHandler(new AttachEvent.Handler() {
                    @Override
                    public void onAttachOrDetach(AttachEvent event) { 
                        // hide the popup:
                        showPopup(false);
                        Scheduler.get().scheduleFinally(resetPopupDimensions);
                        Scheduler.get().scheduleFinally(normalCursor);
                    }
                });
            }
            else if(!frame.getUrl().equalsIgnoreCase(url)) {
                frame.setUrl(url);
            }
            return frame;
        }
    }

    /**
     * static inner-class for holding pages activated by the app's main menu commands
     */
    public static class Pages {
        /** */
        public static final String PAGE1 = "foo";
        /** */
        public static final String PAGE2 = "bar";
        /** */
        public static final String PAGE_1A = "baz";
        /** */
        public static final String PAGE_1B = "qux";
        /** */
        public static String lastPage;
        /** */
        public static String lastPage1SubPage;
        /** */
        public static String unsavedMessage;
        /** */
        private static HashMap<String, AppControlPresenter> pageMap;
        /** */
        private static AppControlPresenter presenter;
        /** */
        private static Composite view;

        /**
         * initializes the hashmap of pages  
         */
        public static void init() {
            pageMap = new HashMap<String, AppControlPresenter>();
        }

        /**
         * @returns true if the name of the token is equal to one of the pages
         * @param token the name to check
         */
        public static boolean has(String token) {
            return token.equalsIgnoreCase(PAGE1)            ||
                   token.equalsIgnoreCase(PAGE2)            ||
                   token.equalsIgnoreCase(PAGE_1A);
        }


        /**
         * Gets the correct page container to display as a Composite
         * @param page the token name of the page
         * @return Composite page
         */
        public static Composite get(String page) {
            view = null;
            presenter = null;
            if(page.equalsIgnoreCase(PAGE1)) {
                if(pageMap.get(PAGE1) == null) {
                    pageMap.put(PAGE1, new Page1Presenter(PAGE1)); 
                    page1Container = ((AppControlContainerPresenter) pageMap.get(PAGE1)).getContentPane();
                }
                presenter = pageMap.get(PAGE1);
                lastPage = page;
                mainAppPresenter.setCurrentMenuItem(page);
            }
            else if(page.equalsIgnoreCase(PAGE_1A) ||
                    page.equalsIgnoreCase(PAGE_1B) {
                if(pageMap.get(PAGE1) == null) {
                    pageMap.put(PAGE1, new Page1Presenter(PAGE1)); 
                    page1Container = ((AppControlContainerPresenter) pageMap.get(PAGE1)).getContentPane();
                }
                presenter = pageMap.get(PAGE1);
                lastPage1SubPage = page;
                view = ((AppControlContainerPresenter)presenter).setCurrentPage(page);
            }
            else if(page.equalsIgnoreCase(PAGE2)) {
                if(pageMap.get(PAGE2) == null) {
                    pageMap.put(PAGE2, new Page2Presenter(PAGE2));
                }
                presenter = pageMap.get(PAGE2);
                lastPage = PAGE2;
                mainAppPresenter.setCurrentMenuItem(page);
            }
            else if(External.has(page)) {
                throw new Error("App Controller Error -- Use 'External' inner-class for: " + page);
            }
            else {
                throw new Error("App Controller Error -- Page name not found: " + page);
            }
            if(view == null) {
                view = (Composite)presenter.view();
            }
            view.addAttachHandler(new AttachEvent.Handler() {
                @Override
                public void onAttachOrDetach(AttachEvent event) {
                    AppController.showPopup(false);
                    presenter.updateAttachOrDetach(event);
                    Scheduler.get().scheduleFinally(resetPopupDimensions);
                    Scheduler.get().scheduleFinally(normalCursor);
                }
            });
            return view;
        }

        /**
         * Gets the current AppControlPresenter for the last page.
         * @returns the current AppControlPresenter  
         */
        public static AppControlPresenter getCurrentPresenter() {
            return presenter;
        }

        /**
         * Gets an AppControlPresenter from the pageMap.
         * @param token the name of the presenter
         * @returns the AppControlPresenter  
         */
        public static AppControlPresenter getPresenter(String token) {
            return pageMap.get(token);
        }

        /**
         * Returns true if the page is already loaded.
         * @param token name of the page
         */
        public static boolean alreadyLoaded(String token) {
            MainApp.debug(1, "[already loaded: " + presenter.toString() + " (token: " + token + ")");
            return presenter.toString().equalsIgnoreCase(token);
        }

        /**
         * Returns true if the page is visible
         * @param page the token name of the page
         */
        public static boolean isVisible(String page) {
            UIObject component = pageMap.get(page).view();
            return !(component.getOffsetHeight() == 0 && component.getOffsetWidth() == 0);
        }

        /**
         * Returns true if the page is visible
         * @param presenter the AppControlPresenter instance
         */
        public static boolean isVisible(AppControlPresenter presenter) {
            UIObject component = presenter.view();
            return !(component.getOffsetHeight() == 0 && component.getOffsetWidth() == 0);
        }

        /**
         * Returns true if the application has unsaved data.
         * Iterates through all the pages and checks each presenter.
         */
        public static boolean unsavedData() {
            if(pageMap.isEmpty()) return false;
            boolean unsaved = false;
            for(Map.Entry<String, AppControlPresenter> entry : pageMap.entrySet()) {
                AppControlPresenter presenter = entry.getValue();
                if(presenter != null && presenter.unsavedData()) {
                    MainApp.debug(1, "(!) " + presenter.toString() + " has unsaved data");
                    unsavedMessage = presenter.dataDescription();
                    unsaved = true;
                    break; // just need to know one exists for now (window closing event)
                }
            }
            return unsaved;
        }

        /**
         * Called on a resize event on the window. Iterates through all the pages
         * and tells their presenters to resize their content.
         */
        public static void resize() {
            for(Map.Entry<String, AppControlPresenter> entry : pageMap.entrySet()) {
                AppControlPresenter presenter = entry.getValue();
                if(presenter != null && isVisible(presenter)) {
                    presenter.resize();
                }
            }
        }
    } //end class Pages

    /**
     * @returns true if the history token is equal to any of the pages in the app 
     */
    public static boolean hasHistory() {
        String token = History.getToken();
        return External.has(token) || Pages.has(token);
    }

    /**
     * Starts the login view at the root layout level
     */
    public static void goLoginScreen() {
        //check for reload:
        if(hasHistory()) {
            MainApp.debug(1, "(!) AppController has History on Login");
            reloaded = true;
        }
        else {
            reloaded = false;
        }
        RootLayoutPanel.get().clear();
        RootLayoutPanel.get().add(new LoginPresenter(LOGIN_OBJECT_NAME).view());
    }

    /**
     * @returns the last "Page1" page
     */
    public static String getLastPage1Page() {
        if(Pages.lastPage1SubPage == null || Pages.lastPage1SubPage.isEmpty()) {
            Pages.lastPage1SubPage = DEFAULT_INITIAL_PAGE1_SUB_PAGE;
        }
        return Pages.lastPage1SubPage;
    }

    /**
     * Tells the app to start with the Page1 page.
     * @param username the username of the person logged-in
     */
    public static void goMainApp(String username) {
        //hide the login background:
        RootPanel.getBodyElement().getStyle().setProperty("background", "none");
        mainAppPresenter = new MainAppPresenter(username);
        RootLayoutPanel.get().clear();
        mainAppPresenter.go(RootLayoutPanel.get());
        //get the center panel:
        container = mainAppPresenter.getContainer();
        //check for reload:
        //NOTE: the token will be empty if the user refreshes 
        //      and navigates all the way back to the zero-state 
        //      from the login screen. 
        //NOTE: this logic may change after user-persistence is implemented
        if(hasHistory() || History.getToken().isEmpty()) {
            // reset the reloaded flag:
            reloaded = false;
            if(History.getToken().isEmpty()) {
                //land on the first page:
                History.newItem(AppController.Pages.PAGE1);
            }
            else {
                MainApp.debug(2, "(!) AppController has History on reload: " + History.getToken());
                History.fireCurrentHistoryState();
            }
        }
        else {
            //land on the first page:
            History.newItem(AppController.Pages.PAGE1);
        }

    }

    /**
     * 
     */
    public static void checkIfSessionActive() { 
        loginRpcService.loginFromSession(new AsyncCallback<LoginSummary>() {
            @Override
            public void onFailure(Throwable throwable) {
                goLoginScreen();
            }

            @Override
            public void onSuccess(LoginSummary loginSummary) {
                if (loginSummary.getErrorString() != null)
                    goLoginScreen();
                else
                    goMainApp(loginSummary.getUser().getName());
            }
        });
    }

    /**
     * 
     */
    public static void sessionLogout() {
        DialogBoxWidget.confirm(200,
                "Logout",
                "Are you sure you want to log out?",
                new ConfirmDialogCallback() {
                    @Override
                    public void onAffirmative() {

                        loginRpcService.logout(new AsyncCallback<Void>() {
                            @Override
                            public void onFailure(Throwable throwable) {
                                goLoginScreen();
                            }

                            @Override
                            public void onSuccess(Void aVoid) {
                                goLoginScreen();
                            }
                        });
                    }

                    @Override
                    public void onCancel() {
                    }
                });

    }

    /**
     * Shows or hides the "Under Construction" popup if UNDER_CONSTRUCION is true.
     * @param show true to show and false to hide
     */
    public static void showPopup(boolean show) {
        if(MainApp.UNDER_CONSTRUCTION && popup != null) {
            if(show) {
                popup.show();
            }
            else {
                popup.hide();
            }
        }
    }

    /**
     * Called by every history event fired (including the back and forward buttons).
     * Ignores the login and empty index historically.
     * @param token the name of the page to load
     */
    public static void go(String token) {
        if(reloaded) {
            normalCursor.execute();
        }
        if(token == null || token.isEmpty() || reloaded == true) return;
        MainApp.debug("<history changed> - AppController.go()-> " + token);
        // build the popup message for all unfinished pages:
        if(MainApp.UNDER_CONSTRUCTION) {
            if(popup == null) {
                popup = new DecoratedPopupPanel(false);
                popup.ensureDebugId(POPUP_DEMO_ID);
                popup.addStyleDependentName(POPUP_DEMO_ID);
                popup.setWidget(new HTML(new Image("images/workingman.png") + POPUP_DEMO_STATEMENT + new Image("images/workingmanFLIP.png")));
            }
        }
        // check token for which page to return:
        if(token.equalsIgnoreCase(External.EXTERNAL_URL_1)) {
            MainAppPresenter.clearActiveMenuItems();
            setExternalContentURL(External.get(token));
        }
        else if(token.equalsIgnoreCase(External.EXTERNAL_URL_2)) {
            MainAppPresenter.clearActiveMenuItems();
            setExternalContentURL(External.get(token));
        }
        else if(token.equalsIgnoreCase(Pages.PAGE1)) {
            setContent(Pages.get(Pages.PAGE1));
            setPage1Content(Pages.get(getLastPage1Page()));
        }
        else if(token.equalsIgnoreCase(Pages.PAGE_1A) ||
                token.equalsIgnoreCase(Pages.PAGE_1B)) {
            setContent(Pages.get(Pages.PAGE1));
            setPage1Content(Pages.get(token));
        }
        else if(token.equalsIgnoreCase(Pages.PAGE2)) {
            setContent(Pages.get(Pages.PAGE2));
        }
        else { // default behavior for a page not described:
            MainApp.debug(2, "(!) Unknown page: " + token);
            setContent(Pages.get(token));
        }
    }

    /**
     * Called by MainApp on a window resize event.
     * @param e the ResizeEvent
     */
    public static void resize(ResizeEvent e) {
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
            @Override
            public void execute() {
                if(mainAppPresenter != null) {
                    mainAppPresenter.resize();
                }
                Pages.resize();
                Scheduler.get().scheduleFinally(resetPopupDimensions);
            }
        });
    }

    /**
     * Changes the cursor to "wait" or "auto" depending on the parameter
     * @param wait true to set the cursor to waiting
     */
    private static void waitCursor(Boolean wait) {
        if(wait) {
            RootPanel.getBodyElement().addClassName(CURSOR_WAIT_CLASS);
        }
        else {
            RootPanel.getBodyElement().removeClassName(CURSOR_WAIT_CLASS);
        }
    }
    /**
     * Private Constructor which initializes the Pages object.
     */
    private AppController() {
        Pages.init();
    }

    /**
     * Sets the content of the main app container to one of the "Pages."
     * @param c the Composite widget to be added
     */
    private static void setContent(Composite c) {
        container.clear();
        container.add(c.asWidget());
    }

    /**
     * Sets the content of the main app container an external URL.
     * @param f the Frame by which external web sites are added
     */ 
    private static void setExternalContentURL(Frame f) {
        container.clear();
        container.add(f);
        // must reset the width and height every time:
        f.getElement().getStyle().setWidth(100, Unit.PCT);
        f.getElement().getStyle().setHeight(100, Unit.PCT);
    }

    /**
     * Sets the content of the Page1 container to one of the sub pages.
     * @param c the Composite widget to be added
     */
    private static void setPage1Content(Composite c) {
        page1Container.clear();
        page1Container.add(c.asWidget());
    }
}

AppControlPresenter.Java:

package com.*;

import com.google.gwt.event.logical.shared.AttachEvent;
import com.google.gwt.user.client.ui.Composite;

/**
 * Base interface for all 'Presenters' used by AppController.Java
 * NOTE: classes that implement this interface do not launch the presenter's view 
 * into the provided container; rather, the view is retrieved and used by the 
 * AppController instance by calling the 'view()' method
 */
public interface AppControlPresenter {

    /**
     * Gets the view (for use in AppController.Java)
     */
    public Composite view();

    /**
     * Indicates if current search data is present and unsaved.
     * @returns true to if a search is still active  
     */
    public boolean unsavedData();

    /**
     * Called on resize event to notify presenters with visible
     * components that need resizing for different screen sizes.
     * @returns true if elements were resized
     */
    public boolean resize();

    /**
     * Called on attachEvents to tell the presenter to update.
     * @param event the AttachEvent
     */
    public void updateAttachOrDetach(AttachEvent event);

    /**
     * Gets the message to display for unsaved data.
     * @returns a message String describing the data
     */
    public String dataDescription();

    /**
     *  Gets a fully qualified name for use in comparisons
     * @return the name of this presenter used by the <code>AppController</code>
     */
    public String toString();
}

AppControlContainerPresenter.Java:

package com.*;

import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.LayoutPanel;

/**
 */
public interface AppControlContainerPresenter extends AppControlPresenter {

    /**
     * 
     * @return
     */
    public LayoutPanel getContentPane();

    /**
     * 
     * @param pageName
     * @return
     */
    public Composite setCurrentPage(String pageName);
}
0
PAINKILLER

Sie können MVP-Muster verwenden. Hier ist eine einfache Bibliothek https://code.google.com/p/gwt-simple-mvp/wiki/GettingStarted .

Und Sie können den Code in mehrere js-Dateien aufteilen. https://code.google.com/p/gwt-spliting/

0
Tito100