Adding Content to a GWT Horizontal Panel from another class - gwt

I am trying to populate the right-hand-side of a HorizontalPanel used in an onModuleLoad() method from another class (containing other widgets) so to keep the code separate.
What I am trying to achieve is similar to a PHP include where I can alter the code in another class and it will affect the right-hand panel only.
Does this other class have to be a composite widget? Or can I do a similar thing that I do when creating the Entry class?

I'm not sure if you mean you want to load a complete different GWT module on the right-hand panel or simply want to load a different class. I assume the latter.sense.
In such case a GWT TabPanel, but positioned Vertical. This is a combination of a DeckPanel and a TabBarPanel. In GWT there is standard VerticalTabPanel available, but you can find one in the open source cobogw library, see http://www.cobogw.org. An example including source code can be found on the demo page: http://cobogw.googlecode.com/svn/demo/WidgetsDemo.html#VerticalTabPanel
The example also uses a LazyPanel. This means each class is initialized only when the user clicks on the link, which makes startup a lot faster.

Just add the reference to the horizontalpanel to some other class (like a controller class or main panel class) and then call into this class from your right side panel. You can even have a controller class that holds this static horizontalpanel with a method like
HorizontalPanel hPanel; //set this from on module load, or controller.create method for instance
public static setRightContents(Panel panel){
hPanel.add(panel)
}
and just call this from the other class Controller.setRightContents(myNewRightPanel).
Really you just need to stop thinking this is a website and start thinking more of a thick client application using even driven programming.

Related

How to create a custom Pane for use in SceneBuilder where controls layout correctly

I am trying to provide some default behavior to a standard Pane in Java FX. I would like to use this Pane in SceneBuilder. For some reason the layout isn't working as I would expect.
I created the following component:
public class GroupBox extends Pane {
public void configureGroupBox(String title) {
//Perform needed set up here.....
}
}
I have exported this control into a JAR file and imported that control into SceneBuilder. I am able to select this control in SceneBuilder and add it to my FXML.
However, the problem starts when I attempt to add controls within it. Even though this extends a javafx.scene.layout.Pane the layout engine of SceneBuilder is pushing all controls to the top left and overlapping them, rather than having no layout instructions.
Is what I am trying to do possible? If so, is there something else I need to do? At this point, my control is just an empty extension of the Pane class.
Thanks.
That is a Scene Builder limitation.
SB provides full operation for builtin containers only (i.e. the ones that are part of JavaFX). For custom containers, it provides limited operations: typically SB allows to drop a component inside but not to move it (because it considers that extending Pane does not imply free positioning of children).

GWT - Keep widget instance between modules

I'm developing an application consisting of 3 modules.
The users can start a web chat (implemented as a widget) and then navigate through the modules. I would like the web chat widget to be kept during the navigation.
I've added a static field in the widget containing the current instance, but it is only persisted while I remain in the same module. If I change module the widget is re-created by scratch.
Is there a way to define an object with application scope?
A better solution (than keeping global state) would be to use Dependency Injection and inject your widget to all relevant views.
Using gin it'd look like this:
#Singleton
public class CommonWidget {
}
public class View1 {
#Inject
public View1(CommonWidget widget) {
}
}
public class View2 {
#Inject
public View2(CommonWidget widget) {
}
}
Now, widget in View1 and View2 point to the same widget.
The problem is that you have to be careful when using this widget - remember that you can only add a widget once to the DOM, so before adding it in View2, you have to remove it from View1.
I think that instead sharing the widget this way, you should either share the messages between two chat widgets or better yet, move the chat widget "above" the views (either literally or figuratively), so that there's only one instance.
Of course, there are more steps to setting up gin, but you can read about them in the docs.
You can create any widget in your entry point class (#onModuleLoad), and then reference/call this widget from any activity that needs it. However, I would only recommend this solution in two cases:
A widget is a container for the entire application or part of the application (e.g. top menu, main panel) that is always visible on a screen, so you don't add/remove it from UI - you simply call it to change its state.
A widget is a popup panel or similar (e.g. confirm dialog, error notification, etc.), so reusing it in different activities/views does not cause any problems.
You may want to take a look at Activities and Places design pattern. It supports most typical navigation scenarios, where you move from one Activity/View to another within the same app (container) widget.
UPDATE:
This is a quote from GWT docs about the use of multiple modules:
If you have multiple GWT modules in your application, there are two
ways to approach loading them.
Compile each module separately and include each module with a separate
tag in your HTML host page.
Create a top level module XML
definition that includes all the modules you want to include. Compile
the top level module to create a single set of JavaScript output.
The
first approach may seem the easiest and most obvious. However, the
second approach will lead to much better end-user performance. The
problem with loading multiple modules is that each module has to be
downloaded separately by the end-user's browser. In addition, each
module will contain redundant copies of GWT library code and could
possibly conflict with each other during event handling. The second
approach is strongly recommended.

Using an EditorPart inside a Composite

I'm new to RCP and I'm trying to create a new View or Editor. At the current state I'm extending ViewPart.
The Layout I want to achieve is a SashForm where both sides have a CTabFolder. One of the sides of the SashForm is basically a MultiPageEditorPart. One of it's tabs should be an editor for a specific language with syntax highlighting and similar features. From what I understand I could extend AbstractTextEditor for that (and maybe use it as one tab of a MultiPageEditorPart).
If I try to achieve this layout with a ViewPart as top level container which contains a SashForm, I can't add an EditorPart to one of the sides of the SashForm. Of course I could implement this editor from scratch as Composite but I want to avoid that.
I am also willing to use an EditorPart or MultiPageEditorPart as top level container but then I'd have to find a way to get the SashForm layout working. The whole editor should be splited first and then each side should have tabs.
Does anyone have an idea how to solve this?
If anything is unclear please ask. I've got the feeling I've put this into words a little complicatedly.
I think you should just make a ViewPart that has a text editing component of some kind on the left, instead of trying to find a way to use an EditorPart. All that EditorPart is really buying you is dirty flag management and Save support; syntax highlight and so forth you can add to the text editing component yourself (I was surprised at how few drop-in text components I found while poking around the internet just now; I expected to find "a few" and instead I found "basically none").
You can see one way to do very rudimentary syntax highlighting with a StyledText component here: JavaSourceCodeViewer
To see a more robust implementation of things like syntax highlight and autocomplete, take a look at the class that Eclipse uses for the editing of Java source code: CompilationUnitEditor
I think what you are trying to achieve is quite complicated and might require a lot of extra work. See an editor is not just different controls laid out in some order, but it has a lot of additional features that any editor class expects to work. These include things like selection service and action bars etc, that you will need to hook in to ensure smooth running.
That said, it should be possible to achieve what you are hoping for. You can have a look at the source code of the MultiPageEditorPart itself to see how it converts a single editor into a multi page editor, which is capable of hosting a completely independent editor on each of its pages. You would need to achieve something similar if you want your editor to host two MultiPageEditorParts separated by a sash. If you want to carry on, you should start implementing some stuff and if you run into any problems, post them here. You would be able to get a lot better help then.
You need something like MultiPageEditorSite. Use it for inspiration when implementing an EditorSiteDelegate. MultiPageEditorSite has support for separate keybindings between the pages, for example.
class ChildEditorSite implements IEditorSite {
IEditorSite parent;
public Object method() {
return parent.method();
}
}
Using this class, you can easily do the following in your main EditorPart:
class MyCoolPart extends EditorPart {
public void createControl(Composite parent) {
EditorPart child1 = new MyChild();
child1.init(new ChildEditorSite(getEditorSite()), myInput);
EditorPart child2 = new MyChild();
child2.init(new ChildEditorSite(getEditorSite()), myInput);
child1.createPartControl(parent);
child2.createPartControl(parent);
}
}
Be sure to also dispose of your children correctly when you dispose of your MyCoolPart. Please note that this only works in the most basic of cases. An EditorPart that is a DocumentEditor or that relies on IPersistablePart or implements listeners/adapters for confirming a save is probably going to require a lot more Lifecycle management...

GWT UiBinders Interaction between modules

Im new to GWT, this should be a simple question i hope.
Imagine that i made two Uibinders Modules or two independent widgets.(this a simplify example to expose my problem)
one is a set of buttons (ButtonPanel) and the other image to been show when i press a button from the previous panel(ImagePAnel) with a label to be the title of the image.
How can i reach the wiget the imagePanel to actuate when there are a handler click from the buttons in the (ButtonPanel)
Thanks for the help.
I recommend you to use MVP Pattern for Development and add all events in the Presenter.
Or Else you can use the following technique within the UIBinder's Java File
#UiHandler(value={"openButton"})
public void onOpenButtonClick(ClickEvent clickEvent){
//ADD THE BUTTON LOGIC HERE
}
Just Create an Object of the Images & the ImagePanel to be loaded and add it on button click using this.
I can't say I understand exactly what you are trying to accomplish but in general the best way for different components in a GUI application to communicate is to use the eventbus pattern. There's one global Eventbus object in the application that lets components subscribe to a specified type of event that are fired from any place in your application. This way you avoid spaghetti code and your components are loosely coupled.
http://code.google.com/webtoolkit/articles/mvp-architecture.html#events
I typically create a third component that is the container for the Button and Image components you defined. This component sets itself as a callback for the two and contains logic to integrate the two.

GWT - connect two modules via EventBus

We use MVP with custom EventBus to navigate across the views. One of our GWT module loads an ebook within a view. We have a button named "Expand", which upon clicked, loads the ebook in expanded mode thereby hiding the header, footer, etc.
Let us say the view (UiBinder) with "Expand" button is named as "ShowEbookView". Upon clicking "Expand" button, the ClickEvent is captured and fired to the EventBus. The logic onExpand(final ExpandEvent expandEvent) is written in the same "ShowExpandedMod" class.
Everything is okay, but we have a button named "Popout" in the expanded mode, which when clicked, should open the Ebook in a NEW page! We need to abstract the "ShowExpandedMod" class so that it can operate with the EbookId and can be used in the new page.
We have created a new Module with EntryPoint class, HTML page and UiBinder page for this new popout window. I am not sure how to proceed now with the abstraction and to use EventBus across different modules to load the same content ... (with re-usability ofcourse)
I've explained to my best, but perhaps not very clear! Please let me know if you want more details.
Thanks!
When you open a new window in browser you basically get a new instance of your GWT app. You can not use EventBus across different browser windows, i.e. across different GWT module instances.
What you can do is:
Add an argument to the Popout page URL. This is easies done via "history tokens" (fragment identifiers), like this http://yourdomain.com/popout.html#theIdOfTheDocument. Then you can retrieve the token via History.getToken()
Use DOM to communicate between browser windows: window.open() in javascript opens a new window and returns a reference to DOM of the new window. You can then access properties and functions of the new window. This is all javascript, in order to make this work in GWT you'll need to wrap it in JSNI.
Try and use MVP4G, in specific - take a look at their multi-modules feature (which utilizes GWT's code splitting capabilities).
This should make things like multiple EventBus's and cross-module event triggers a lot easier to handle.