Wiele stron samouczek w Google Web Toolkit (GWT)
Właśnie zacząłem się uczyć Google Web Toolkit (GWT). Jak zrobić różne strony HTML w mojej aplikacji GWT?
Na przykład Chcę stworzyć aplikację dla księgarni. W tej aplikacji będę miał trzy strony:
- Strona główna, na której będę witał użytkownika i oferował książki użytkownika
- strona do przeglądania książek według kategorii i wyświetlania szczegółów (użyj widżetów GWT) Sprawdź książki online.
Oczywiście mogą być inne strony jak dane użytkownika, Dodaj nową książkę itp. Jaki jest najlepszy sposób na tworzenie różnych stron w GWT i jak Mogę nawigować od strony do strony? Czy są jakieś przykłady lub samouczki? A może w ogóle muszę tworzyć różne strony, Gdy mogę utworzyć całą aplikację na jednej stronie?
8 answers
To, co zwykle robię w takich sytuacjach, to najpierw zaprojektuję Framework strony. Będę miał div dla nagłówka, menu bocznego i stopki. Będę miał również div
w moim HTML dla głównej treści.
Przykład:
<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>
(Jeśli lubisz układy oparte na
Następnie budujesz swój punkt wejścia (w moim przypadku Core.java
) tak, jak zwykle, ustawiając każdy z elementów zgodnie z potrzebami.
RootPanel.get("header").add(new Header());
RootPanel.get("leftnav").add(new NavigationMenu());
RootPanel.get("footer").add(new Footer());
Oczywiście możliwe jest posiadanie statycznej stopki i nagłówek, ale to ani tu, ani tam.
Mam też klasę abstrakcyjną o nazwie "Content". Obiekty zawartości rozszerzają "kompozyt" i będą miały różne metody upraszczania tworzenia i układu nowej strony. Każda strona, którą buduję dla tej aplikacji, czy to ekran pomocy, ekran wyszukiwania, koszyk lub cokolwiek innego, jest typu Content
.
Teraz tworzę klasę o nazwie "ContentContainer". Jest to singleton, który jest odpowiedzialny za zarządzanie " treścią" element. Posiada jedną metodę "setContent", która akceptuje obiekty typu "Content". Następnie zasadniczo usuwa wszystko z" zawartości "
Wreszcie, potrzebujesz sposobu, aby dostać się do tej strony, prawda? To proste:
ContentContainer.getInstance().setContent(new Search());
Umieść powyższe w wydarzeniu on-click gdzieś i jesteś złoty.
Jedyne, co inne widżety muszą być powiązane, to ContentContainer i rodzaj zawartości, którą dodają.
Minusy, które widzę w podejściu ChrisBo, to to, że masz listę, która musi być utrzymywana z tokenów - > stron. Innym minusem jest to, że nie widzę jak możesz mieć rzeczywisty system historii za pomocą tej metody.
Jedną z rzeczy, które oferuje w stosunku do mojego podejścia, jest to, że wszystkie wybory stron są dość scentralizowane. Użyłbym jakiegoś Enum lub przynajmniej statycznej klasy z wartościami łańcuchowymi, aby zapobiec podrabianiu linków.
W obu przypadkach, myślę, że punkt można podsumować następująco: zamień zawartość jakiegoś centralnego elementu strony na podstawie na to, co użytkownik kliknie działania, które wykonują użytkownicy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-11 20:14:06
Użyłbym hiperłącza i lekcji historii. Dobrą rzeczą w klasie Hyperlink jest to, że ustawia ten token (np.#foobar), a wszystko, co musisz zrobić, to złapać zdarzenie, które zostanie wywołane, gdy wartość tokena zostanie zmieniona (ValueChangeEvent). W programie eventHandler zamienisz strony.
Przykład: adres strony powitalnej: www.yourpage.com/#home na tej stronie byłby link do strony "przeglądaj książkę", po kliknięciu linku nowy adres byłby czymś w rodzaju to: www.yourpage.com/#browse
A oto kod:
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");
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-30 13:16:16
Awesome! Połączyłem odpowiedź Chrisa R. z odpowiedzią Chrisa Boesinga, aby wymyślić to:
To jest strona startowa indeksupublic 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());
}
}
To jest kontroler, czyli ContentContainer według Chrisa 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
}
Wtedy możesz pieprzyć hiperłącza i przyciski w dowolnym miejscu w kodzie. (Nie próbowałem jeszcze hiperłączy.)
Button submit = new Button("Submit");
submit.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
FlowControl.go(new MyScreen());
}
});
Dodałem div do mojego HTML
<!-- This is where the application will reside within. It is controlled by FlowControl class. -->
<div id="application"></div>
I teraz wszystkie ekrany muszą wywołać initwidget() w konstruktorze zamiast dodawać do RootPanel, ponieważ jest to klasa złożona, jak
initWidget(myPanel); // all composites must call this in constructor
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-22 22:16:57
Jeśli chcesz, aby była pełna AJAXified (jak aplikacja komputerowa) oczywiście potrzebujesz tylko jednej strony. Następnie wystarczy zmienić zawartość Ciała w zależności od linku.
Ponadto istnieje grupa google dla GWT, która jest bardzo aktywna, i Wiem, że zostało to wcześniej zapytane, wystarczy użyć funkcji "Szukaj".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-30 05:56:20
GWT Multipage - Prosty framework dla wielostronicowych aplikacji GWT.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-21 23:43:19
Możesz użyć MVP patern. Oto mi simple library https://code.google.com/p/gwt-simple-mvp/wiki/GettingStarted .
I możesz podzielić kod na więcej plików js. https://code.google.com/p/gwt-spliting/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-08 13:25:29
[6]} użyłem Chloe S. answer (łącząc odpowiedź Chrisa R. z odpowiedzią Chrisa Boesinga), aby zbudować ten kontroler aplikacji dla działającej aplikacji internetowej GWT. Wersja w produkcji jest testowana (i działa %100), ale ta zredagowana Wersja poniżej będzie musiała zostać zmodyfikowana, aby zintegrować się z Twoją własną aplikacją(zacznij od Zmiany Nazwy klawiszy strony na pozycje menu).
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'>…</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);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-21 03:13:20
Dodaj moduł dla każdej posiadanej strony, który wymaga funkcjonalności GWT. Wykorzystaj ponownie swoje komponenty.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-11 18:48:51