I am new to GWT and GWTP. I know what is GWT Code Split and GWTP Proxy Code Split. I've already red:
http://www.gwtproject.org/doc/latest/DevGuideCodeSplitting.html
http://dev.arcbees.com/gwtp/core/presenters/creating-places.html
I assumed that I understand it. So I've like to used.:
I have application with Administration panel, where only part of users can access. So there is no need to download Administration panel related code for all. So in Administration Presenter I've added #ProxyCodeSplit like follow:
public class AdminAreaPresenter extends Presenter<AdminAreaPresenter.MyView, AdminAreaPresenter.MyProxy> {
#ProxyCodeSplit
#NameToken(Routing.Url.admin)
#UseGatekeeper(IsAdminGatekeeper.class)
public interface MyProxy extends TabContentProxyPlace<AdminAreaPresenter> {}
#TabInfo(container = AppPresenter.class)
static TabData getTabLabel(IsAdminGatekeeper adminGatekeeper) {
return new MenuEntryGatekeeper(Routing.Label.admin, 1, adminGatekeeper);
}
public interface MyView extends View {}
AppPresenter appPresenter;
#Inject
AdminAreaPresenter(EventBus eventBus, MyView view, MyProxy proxy, AppPresenter appPresenter) {
super(eventBus, view, proxy, AppPresenter.SLOT_TAB_CONTENT);
this.appPresenter = appPresenter;
}
}
In other Presenters I have #ProxyStandard instead of #ProxyCodeSplit.
I've run app and log in. then I've opened Network tab in chrome's developer console:
And after opening Administation Panel in application:
As You can see, there is no new resources added to application.
My main app presenter AppPresenter implements interfaces AsyncCallStartHandler, AsyncCallFailHandler, AsyncCallSucceedHandler from: com.gwtplatform.mvp.client.proxy. and I override those methods:
#ProxyEvent
#Override
public void onAsyncCallStart(AsyncCallStartEvent event) {
Window.alert("Async start");
getView().setTopMessage("Loading...");
}
#ProxyEvent
#Override
public void onAsyncCallFail(AsyncCallFailEvent event) {
Window.alert("Async fail");
getView().setTopMessage("Oops, something went wrong...");
}
#ProxyEvent
#Override
public void onAsyncCallSucceed(AsyncCallSucceedEvent event) {
Window.alert("Async success");
getView().setTopMessage(null);
}
And when I enter AdmininArea I am getting to allerts: "Async start", "Async success". So I think that everythink work, but unfortunatelly I don't see any changes in resources. Please help. Am I doing something wrong or what?
Code splitting is disabled in SuperDevMode because it is not compatible with the incremental compiler and would also slow down compilation (see this issue).
To test code splitting, compile your GWT application (mvn clean install gwt:compile) and test it in production mode (take war file from target directory and put it in f.e.: Tomcat server catalog: webapps).
Related
How can I replace default pop-up window when exception throws on top level in RCP 4 application?
You can set a class implementing IEventLoopAdvisor in the application Eclipse Context. This is given all unhandled errors.
Something like:
class EventLoopAdvisor implements IEventLoopAdvisor
{
#Override
public void eventLoopIdle(final Display display)
{
display.sleep();
}
#Override
public void eventLoopException(final Throwable exception)
{
// TODO Your code
}
}
Note: It is extremely important to call display.sleep in the eventLoopIdle method.
A good place to set this up is the #PostContextCreate of your LifeCycle class (if you have one):
#PostContextCreate
public void postContextCreate(final IEclipseContext context)
{
context.set(IEventLoopAdvisor.class, new EventLoopAdvisor());
}
Note: IEventLoopAdvisor is an internal class so normally I would not advise using it, but this use does seem to be allowed.
I have an app which works fine at the moment and uses geolocation. I have a method which calls com.google.gwt.geolocation.client.Geolocation.
I extended the existing entry point and overriden this method to use the native Geolocation library so I don't have any permission popups.
How can I avoid having two modules which takes twice as long to compile?
In GWT normally you have an entry-point per application, or perl .html page, but you can have other scenarios: you could have a module file (.gwt.xml) with multiple entry-points, or a page loading multiple modules (.cache.js), or even you could load the same module (.cache.js) in different pages.
So, in your case, you could maintain one entrypoint and one module file and include the same compiled module in both pages. In this case you have to write some code in your entry point to know what to do in each page:
public void onModuleLoad() {
if (Window.Location.getPath().matches(".*page_1.html.*")) {
// do something
} else {
// do another thing
}
}
Think that in this case you will have all the compiled stuff in both pages, but you could take advantage of gwt code-splitting and make each page load just the stuff it needs:
public void onModuleLoad() {
if (Window.Location.getPath().matches(".*page_1.html.*")) {
GWT.runAsync(new RunAsyncCallback() {
public void onSuccess() {
// do something
}
public void onFailure(Throwable reason) {
}
});
} else {
GWT.runAsync(new RunAsyncCallback() {
public void onSuccess() {
// do another thing
}
public void onFailure(Throwable reason) {
}
});
}
}
The advantages of this approach is that you compile just once for all your site, and you share the same code in all your pages taking advantage of the cache. There are disadvantages as well like your final code is higher, dev-mode could be slower, etc.
I am trying to extending "org.eclipse.ui.startup" extendion point.
but it seems in eclipse e4 ,it does not even getting called.
is this extension is broken in eclipse e4(Juno)
I had the same problem and couldn't find an answer, but in the process I discovered the LifeCycleHandler which is even better for my purpose. It might be a good alternative for you as well.
Just as with the startup-extension you can reference a handler from your plugin.xml:
<property name="lifeCycleURI" value="platform:/plugin/<plug-in-id>/<path-to-handler-class>" />
In the handler you can use annotations to mark the method that is to be invoked as well as dependency injection:
public class StartupHandler {
#Inject
Foo bar;
#PostContextCreate
public void startup(IEclipseContext context) {
// do something
}
}
You can find a detailed example here: https://marcteufel.wordpress.com/2011/05/05/231/
IStartup#earlyStartup() needs the compatibility layer, so it does not work in a pure E4 Application. (see #1)
To launch a process in a pure E4 Application you should use a lifecycle hook. So:
Reference your ApplicationLifecycle handler class from plugin.xml
<property name="lifeCycleURI" value="platform:/plugin/<plug-in-id>/<path-to-handler-class>" />
write your lifecycle handler class
public class ApplicationLifecycleHandler {
#PostContextCreate
public void startup(IEclipseContext context) {
// do initialization
}
}
Add an hook to handle events at Application Startup Complete
#PostContextCreate
public void postContextCreate(final IEventBroker eventBroker, etc .. ) {
//
eventBroker.subscribe(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE,
new EventHandler() {
#Override
public void handleEvent(Event event) {
// Your code executed at startup,
// after application startup is completed
}
});
}
(#1) org.eclipse.ui.startup extension doc
I often minimize Eclipse to read or work on something else for a few minutes while I wait for it to do something (e.g., run a large JUnit test suite, synchronize a huge number of files with a repo, run a long Ant build, etc.). I have to check back every 30 seconds or so to see if it's finished yet. I would like Eclipse to alert me, preferably by blinking its taskbar icon, after it finishes a time consuming operation. Are there any settings or plugins that can make this happen?
I believe is you have Mylyn installed, this should be enabled by default for Windows 7. See here and here. Regarding the post-build actions, I do not know of any existing Eclipse plugins that do this. However, I have not exhaustively searched the marketplace. However, this could be accomplished with existing Eclipse APIs but it would require someone to author a new Eclipse plugin.
The Eclipse Platform jobs framework has an API called IJobManager. A developer could write a new Eclipse plugin that could use this API to listen for job changes and do the following:
Create an eclipse plugin, register a listener to IJobManager on startup.
Once any interesting job is completed, it could fire off some external task/script using normal java process execution API in the JDK
This all could be accomplished in one Java file, probably less than 500 lines long.
You could use this template to setup a basic Eclipse plugin project including build system and have it built and ready to install into your existing Eclipse.
Update I just found a maven archetype for building eclipse plugins with tycho here. It would be my recommendation for someone new to building an eclipse feature/updatesite.
You can create a new plugin project and create this kind of functionality for yourself. The
IJobchangeListener from the Eclipse Jobs API is probably very interesting for you.
The IJobChangeListener is an interface where you can receive notifications for the different type of job states.
I have created a class called JobListener which adds the IJobchangeListener to the JobManager. With the action SampleAction you can register or unregister the listener. that means, if the listener is registered and your application is minimized you will be notified with a MessageDialog (no blinking taskbar).
I found a link where someone made his swing application blink. This functionality should be included in the method public void done(final IJobChangeEvent event). I haven't done this in my test class.
You can also get additional information about the Job with
event.getJob();
Here you are able to check the Job name:
String jobName = event.getJob().getName();
The name of the Job is human readable, for example "Collecting garbage", "Update for Decoration Completion", "Building workspace", etc.
The JobListener class.
/**
* A job listener which may be added to a job manager
*/
public class JobListener {
private MyJobListener listener = null;
private IWorkbenchWindow window = null;
private boolean active = false;
public JobListener(IWorkbenchWindow window) {
this.window = window;
}
/**
* register the job listener
*/
public void register() {
listener = new MyJobListener(window);
IJobManager jobMan = Job.getJobManager();
jobMan.addJobChangeListener(listener);
active = true;
}
/**
* unregister the job listener
*/
public void unregister() {
IJobManager jobMan = Job.getJobManager();
jobMan.removeJobChangeListener(listener);
active = false;
}
public boolean isActive() {
return active;
}
class MyJobListener implements IJobChangeListener {
private IWorkbenchWindow window;
public MyJobListener(IWorkbenchWindow window) {
this.window = window;
}
#Override
public void sleeping(IJobChangeEvent event) {
}
#Override
public void scheduled(IJobChangeEvent event) {
}
#Override
public void running(IJobChangeEvent event) {
}
#Override
public void done(final IJobChangeEvent event) {
window.getShell().getDisplay().asyncExec(new Runnable() {
#Override
public void run() {
if(window.getShell().getMinimized()) {
MessageDialog.openInformation(
window.getShell(),
"Test",
"Job " + event.getJob().getName() + " done.");
}
}
});
}
#Override
public void awake(IJobChangeEvent event) {
}
#Override
public void aboutToRun(IJobChangeEvent event) {
System.out.println("About to run: " + event.getJob().getName());
}
}
}
I called this class from a class called SampleAction.java
public class SampleAction implements IWorkbenchWindowActionDelegate {
private IWorkbenchWindow window;
private JobListener listener;
/**
* The constructor.
*/
public SampleAction() {
}
public void run(IAction action) {
if(listener.isActive()) {
listener.unregister();
MessageDialog.openInformation(
window.getShell(),
"Lrt",
"Unregistered");
}
else {
listener.register();
MessageDialog.openInformation(
window.getShell(),
"Lrt",
"Registered");
}
}
public void selectionChanged(IAction action, ISelection selection) {
}
public void dispose() {
}
public void init(IWorkbenchWindow window) {
this.window = window;
this.listener = new JobListener(window);
}
You can get started with eclipse plugin development by creating a new plugin project:
File > New > Project > Plugin Project
I used the Hello World plugin project template to test the code above.
I am learning GWT and i have read at multiple places that using MVP architecture is best suitable to develop a GWT Application
I have also read that its easy to do testing using the MVP ARCH.Can somebody explain me why its easy to do testing using the MVP architecture.
Also i am working on a project using MVP and i find it very tedious to make the view connect to the data base.I mean i have to update my presenter,service,serviceAsync,servicImpl,Facades in order to make connection to database.
So can somebody provide me the essence of MVP for GWT?i would appreciate a couple of examples.
Separation between the presenter (which contains logic) and view (a dumb wrapper around UI controls) allows you to:
write unit tests for the presenters that can run without needing the corresponding environment (desktop, browser, GWT widgets)
reuse front-end logic without being tied to a particular set of widgets/UI framework
The latter use case is rare, so let's focus on the MVP model's suitability for automated, programmatic testing. With a team of developers this often takes the form of a continuous build/test cycle using Hudson (or similar) on a headless server, where it's not practical to open a web browser, create controls, etc. every time a test is run.
Typical usage of MVP+GWT is that views implement an interface provided by the presenter, and often this interface is defined in terms of other generic interfaces. Here's a very simple presenter that increments a numeric label when a button is clicked - note that instead of exposing the TextBox and Button directly, the view returns generic HasText and HasClickHandlers instances:
public class ButtonClickPresenter {
public interface View {
HasText currentValue();
HasClickHandlers incrementButton();
}
private final View myView;
private int currentValue = 0;
public ButtonClickPresenter(View myView) {
this.myView = myView;
this.myView.currentValue().setText("0");
this.bind(); // for the sake of demonstration
}
public void bind() {
this.myView.incrementButton.addClickHandler(
#Override
new ClickHandler() {
void onClick(ClickEvent event) {
currentValue ++;
myView.currentValue().setText(
Integer.toString(currentValue));
}
});
}
}
The "real" view returns UI widgets (created via UiBinder in this example):
public class ButtonClickView implements ButtonClickPresenter.View {
// ... skipped UiBinder initialisation ...
#UiField Label currentValueLabel;
#UiField Button incrementButton;
#Override
public HasText currentValue() {
return currentValueLabel;
}
#Override
public HasClickHandlers incrementButton() {
return incrementButton;
}
// ... etc ...
}
whereas unit tests create a dummy implementation (or use Mockito, EasyMock, etc.) and thus don't require any UI components:
public class ButtonClickPresenterTest {
ButtonClickPresenter presenter;
ClickHandler currentHandler;
String currentText;
#Before
public void setUp() {
presenter = new ButtonClickPresenter(
// dummy view - just stores label text in a String and
// keeps track of the Presenter's click handler
new ButtonClickPresenter.View() {
#Override
public HasText currentValue() {
return new HasText() {
#Override public String getText() { return currentText; }
#Override public void setText(String text) { currentText = text; }
};
}
#Override
public HasClickHandlers incrementButton() {
return new HasClickHandlers() {
#Override
public HandlerRegistration addClickHandler(ClickHandler handler) {
currentHandler = handler;
}
};
}
});
}
#Test
public void testIncrement() {
// initial value
assertEquals("0", currentText);
// clicking the button should increment the number
currentHandler.onClick(null);
assertEquals("1", currentText);
}
}
As for your next paragraph: your views shouldn't be connecting to the database at all! The presenter should request data via Service/ServiceAsync (or an abstraction such as gwt-dispatch or gwt-platform), then call methods on the view to populate the UI.
By the way, those last two links (along with gwt-presenter) are a good start if you're looking for GWT MVP code samples - combined with Google GIN they provide frameworks for tying all this stuff together.
Having said all that, I agree - the combination of GWT+MVP+Java can be hard work and extremely verbose (I'm glad I don't have to work with it much these days). The alternative, though, is even less attractive: an untestable, unmaintainable ball of spaghetti...
You might like to have a look at the sample gwt-platform application blogged about here-> http://uptick.com.au/content/serendipity-working-gwt-platform-and-smartgwt.
Cheers
Mark