我正在尝试设计我的第一个超简单的GWT应用程序,它利用了GWT的大部分主要API功能。我认为我大概有70-80%的路在那里,但是在倾注了GWT文档,无数文章,并在SO上发布了许多其他与GWT相关的问题之后,我仍然很难理解最后的问题。 20 - 30%需要完全放置这个应用程序。
我已经调用了第一个测试应用ClickItToWinIt
,我希望它看起来像这样:
当用户点击" Win"按钮,图片(" win-pic.png
")会弹出左侧的图像框。当用户点击" Lose"按钮,图片(" lose-pic.png
")会弹出同一帧。用户可以在按钮之间来回点击以显示不同的图片。这将是一个单页应用程序,在我的机器上本地托管,只需要包含1个主页,1个模块/入口点等。
请注意,对于这样一个简单的ClickItToWinIt
应用,下面提出的打包/类结构肯定有点过分。但是,不久之后我想继续使用GWT进行更大更好的事情,所以在我开始使用更复杂的UI来处理更大的应用程序之前,我对正确的GWT编码有所了解是非常重要的。
此外,下面提出的结构基于谷歌似乎不知疲倦地鼓励的3 GWT原则:
最后一项:通常,在我的PHP webdev时代,我使用了" themes / skins"的概念。在我的一些网站中,通过使用不同的CSS文件部署网站,该文件只是将不同的样式规则应用于相同的DOM元素。因此,我可能会有一个" normal-styles.css
"使网站看起来正常"的文件,但也有#34; facebook-styles.css
"文件,为网站提供Facebook的外观(颜色,字体等)等。我想在这里完成同样的事情,并提出一个net.bfodder.c2w.client.views.themes
包将有{ {1}}中的子类。这些子类将以某种方式在构建时注入/烘焙到视图/演示者中,并为我提供一种使用不同主题或外观部署应用程序的方法。我相信这是正确的方法,因为(如果我对AbstractTheme
和ClientBundle
的理解是正确的话)GWT 似乎有对象的CSS样式进入GWT POJO。我的CssResource
子类会以某种方式绑定到AbstractTheme
并为我的所有CssResource
定义样式。
所以这里是Widget
的{{1}}结构(我正在使用Google-Eclipse插件在Eclipse 3.7 Indigo中开发):
src/main/java
ClickItToWinIt
适用于任何不属于任何一个特定ClickItToWinIt/
src/main/java/
net.bfodder.c2w
net.bfodder.c2w.client
MainModule (implements EntryPoint)
AppController
ClientFactory
net.bfodder.c2w.client.views
net.bfodder.c2w.client.views.ui
WinButton (extends Composite implements ClickHandler; hasA TextButton)
LoseButton (extends Composite implements ClickHandler; hasA TextButton)
ImageViewer (extends Composite; hasAn Image)
net.bfodder.c2w.client.views.containers
MainContainer
ButtonContainer
ImageContainer
net.bfodder.c2w.client.views.displays
WinActivity (extends AbstractActivity implements AcceptOneWidget)
LoseActivity (extends AbstractActivity implements AcceptOneWidget)
net.bfodder.c2w.client.views.themes
AbstractTheme
NormalTheme
FacebookTheme --> I really dont't care about FB, just using as an example of a well-known theme/skin
net.bfodder.c2w.client.presenters
IPresenter
ButtonPresenter (extends AbstractActivity implements IPresenter)
ImagePresenter (extends AbstractActivity implements IPresenter)
net.bfodder.c2w.client.history
InitialPlace (corresponds to http://localhost/clickittowinit)
WinPlace (corresponds to http://localhost/clickittowinit/#winning)
LosePlace (corresponds to http://localhost/clickittowinit/#losing)
net.bfodder.c2w.client.events
EventBus impl and GwtEvent impls
net.bfodder.c2w.server
Not worried about server-side for now; I think I "get" that much!
子类的奇怪的应用级业务逻辑。 AppController
是一切开始的地方(DI,开始初步IPresenter
等)。按钮放在MainModule
内,Activity
放在ButtonContainer
内,两个内部容器放在ImageViewer
内(我假设在ImageContainer
中创建。至于这些UI组件的布局和样式,就像我说的那样,这将取决于注入/配置的MainContainer
在其规则集中定义的内容。
我使用推荐的MainModule
here来方便地访问应用程序GWT管道的主要部分。
关于MVP"东西",这就是我的想法:
AbstractTheme
就像我上面说过的那样,我相信我几乎就在那里,我只是在艰难的时间弥合一些事情上的差距。所以我问:
ClientFactory
子类以使用public class WinActivity extends AbstractActivity {
private final ClientFactory clientFactory;
private final WinPlace place;
public WinActivity(ClientFactory clientFactory, WinPlace place) {
this.clientFactory = clientFactory;
this.place = place;
}
@Override
public void start(AcceptsOneWidget panel, EventBus eventBus) {
ImagePresenter presenter = clientFactory.getImagePresenter();
// Inject the presenter with any stateful data here
// presenter.setImage(getWinImageUri());
presenter.go(panel);
}
}
和AbstractTheme
,以便我的应用注入/配置正确的主题,并且客户端浏览器下载正确的CSS文件( CssResource
或ClientBundle
)?normal-style.css
(来自经典MVP),facebook-style.css
,"显示区域"之间的关系(IPresenter
)和AbstractActivity
s?这里是否存在1对1对1对1的关系,或者GWT是否打算为每个AcceptsOneWidget
或其他一组比率设置多个显示区域?Place
与GWT的历史记录API相关联?因此,如果用户点击AbstractActivity
,WinPlace
,WinButton
,如何将其保存在浏览器历史记录中,以便他们可以点击前进/后退浏览器按钮并一遍又一遍地重新创建此使用模式?LoseButton
后,会在事件总线上放置一些点击事件。在哪里以及如何将处理程序/侦听器连接到EventBus,它将知道:(a)更改WinButton
中的图像,以及(b)将此状态更改存储在History API中?WinButton
的想法,遗憾的是,ImageViewer
实际上看起来没有提供任何代码段。任何人(熟悉GWT的AppController
模式)是否可以对这看起来如何?也许它在某种程度上是AppController
子类,没有特定的AppController
或视图组件?我不想问这样一个"超级问题"在这里,但我宁愿这样做而不是用6个中等问题弄乱SO,并且一遍又一遍地重复相同的问题设置。另外,有了一个很好的代码示例,它可能一次性回答所有6个,所以我抓住了机会。
提前致谢。