GWT has a lot of similarly-named (and seemingly similarly-purposed) types:
Widget
AcceptsOneWidget
Composite
IsWidget
SimplePanel
When/where is it appropriate to use each of these? What is their relationship to the RootPanel?
Let's first separate interfaces from classes.
Interfaces are great for mocking (thus allowing for testing your app without the need for the sluggish GWTTestCase):
IsWidget: when all you need is a handle on a widget, without depending on the Widget class. This is typically used with MVP as a way to represent the view.
AcceptsOneWidget: when you need a placeholder for a single widget (in the form of an IsWidget). This is typically used with Activities, to insert the view (IsWidget) into the given slot (AcceptsOneWidget).
The classes you list all extend Widget, so they rely on JSNI and (most of the time) need to run in a GWT environment (for unit tests, that means a GWTTestCase):
Widget: the base of all widgets. Implements IsWidget returning itself from asWidget().
Composite: a base class when you need to create a widget built from other widgets while hiding their implementation. While you could extend an existing widget, it's generally better to hide it inside a Composite so you only expose the API you need/want to expose. Composite is about "composition rather than inheritance" and encapsulation. Examples of composites in standard widgets include TabPanel (built from a TabBar and DeckPanel), DateBox (built from a TextBox and DatePicker in a PopupPanel), ValueListBox that wraps a ListBox or ValuePicker that wraps a CellList. In many cases, given that panels accept IsWidget children, you could simply implement IsWidget rather extend Composite, but it's sometimes useful to have a true Widget.
SimplePanel a panel that implements AcceptsOneWidget, useful as a slot when using activities (but you could also easily implement AcceptsOneWidget to insert into any kind of panel)
That being said, Google recently open-sourced GWT-Mockito that plugs Mockito into GWT.create() and uses classloader magic to rewrite JSNI methods and remove final modifiers so you can directly use widgets in tests without the need for GWTTestCase or MVP.
So, all in all, it depends how you approach your code, how you architecture your app. If you use MVP, stick to depending on interfaces only (IsWidget, AcceptsOneWidget) in your presenter so you can easily mock your view in your tests.
Otherwise, or if you want a "simplified MVP" where the view is a UiBinder template, try GWT-Mockito for your tests and directly use widgets.
Of course, you can mix both approaches in the same application. And in any case, build your own widgets as Widgets for low-level things (rarely needed), and Composites or IsWidgets for everything else, rather than extending existing widgets.
You have got all mixed up.
Widget: It allow you to interact with the users. (e.g. Button)
Panels: These are widgets that can contain other panels/widgets. Can be referred as container of widgets.
AcceptsOneWidget: Implemented by panels which will accept only one widget. (e.g SimplePanel)
Composite: A type of widget that can wrap another widget, hiding the wrapped widget's methods. The composite is useful for creating a single widget out of an aggregate of multiple other widgets contained in a single panel.
IsWidget: An interface implemented by almost all known widgets. It Provides access to that widget.
SimplePanel: A panel which contains only one widget.
RootPanel: Is the base panel to which all other panels are added.
Related
Using SWT, Is it possible to create a custom widget and insert it to a Table or Tree as if it was a TreeItem or TableItem?
I tried to create a class and extend TreeItem but I'm getting this warning:
MyClass illegally extends TreeItem
Is there a way to do this?
Most SWT widgets are not designed to be extended and enforce this by checking that the current class is in the org.eclipse.swt.widgets package. This can be worked around but is very strongly discouraged.
Widgets generally contain a lot of platform specific code, an override class might very easily end up using code which will only work on one platform.
There are various other ways to extend tables and trees. Using TableEditor and TreeEditor is one way. Drawing the table/tree yourself using SWT.MeasureItem, SWT.PaintItem and SWT.EraseItem is another.
Both the Book of Vaadin and the Vaadin training course recommend using acom.vaadin.ui.CustomComponent to contain a Layout.
I can understand this in pure theory, to encapsulate the contents without needlessly exposing a specific layout such as GridLayout or HorizontalLayout. Encapsulating has benefits of:
Encouraging de-coupling between classes
Makes it easier to change the layout without having to change the declarations in the outer class.
But in terms of practicality, I assume the rendering of a CustomComponent means extra HTML/CSS layout instructions such as perhaps an another div. The last thing Vaadin rendering needs is yet another layering of HTML structure.
I wonder if this might be old folklore. Perhaps using the visual composing tool in Eclipse accepts only CustomComponent objects rather than Layout objects? (Just a wild guess, I have no knowledge)
➤ Alternatively, why not just declare in the outer class a reference variable of type com.vaadin.ui.Layout to get the same encapsulation?
➤ Am I exaggerating the impact of adding a CustomComponent to Vaadin rendering?
➤ Is there some other benefit of CustomComponent which I’ve failed to perceive?
You can compose the content of a CustomComponent with the Visual Designer. This saves a lot of time in the development process
The main advantage of the CustomLayout is, that you can place your components inside HTML code which you otherwise can't generate via vaadin means.
If this adds more div/html as with native Layouts depends on the specific case.
We ususally use it only when a clean Vaadin only solution would introduce more components/div's or is not possible to implement.
The second idea is the separation of layout and logic, which can be implemented partially with this Layout. You just specify which components you have and then a UI designer (in theorie) could make your HTML code, with the correct blocks where your components will be placed.
In real life I do not find this a real advantage, since the whole CSS, sizing etc. is anyway done with vaadin.
The GWT documentation comes with a tutorial on how to utilize the MVP pattern here. In this example, there are two views, and each replace the other as per the user action.
In these rather simple views, it didn't hurt much to cram all widgets that view has in one single class (view) only. But for a complex view, one would like to create individual views for components (with a corresponding presenter for each such component view), then combine those views into the overall views (this combined view may or may not have a separate combined presenter, since all sub-views already have corresponding presenters). Somewhat similar to creating individual widgets in separate classes that extend Composite, calling initWidget on them, and using them like mainPanel.add(new subPanel()) in the main panel.
So is it possible to do such thing in MVP pattern in GWT?
No, if you do so the entire DOM load in a single shot,even though you put if else conditions inside .
When building large applications with GWT,Using MVP and code splitting is a must – otherwise,
the entire application (i.e. JavaScript bundle) is downloaded in one chunk on the initial
load of the application, which is a good recipe for frustrated users!
By using standard MVP you can
Isolate of User Interface from Business tier
Easily interchangeable Views (user interfaces)
Ability to test all code more effectively
I suppose you are expecting like below
public class MainPageView extends ViewImpl implements MainPagePresenter.MyView {
#UiField
public HTMLPanel mainMenuPanel;
#UiField
public HTMLPanel mainContentPanel;
#UiField
public HTMLPanel mainFooterPanel;
.
.
.
.
.etc
Yes instead of panels as shown above , you can also use classes which have some elements inside.
Update:
To mainMenuPanel you can add your class like mainMenuPanel.add(new MyheaderClass()).
Where MyheaderClass extends of Panel or Widget .So that the all elements in the Class add to the mainMenuPanel
Inside your MyheaderClass class you may add labels, buttons ...etc by using this.add(mybutton)..etc
I'm trying to build a slick-looking GWT panel (my first one) and am stuck trying to decide how to handle its layout.
According to the Layout Javadoc:
Helper class for laying out a container element and its children.
And the LayoutPanel Javadoc:
A panel that lays its children out in arbitrary layers using the Layout class.
So it seems like you can:
Extend a ComplexPanel and use a Layout to manage its layout; or
Use a LayoutPanel which seems to have this functionality built-in; or
Just add elements to an HTMLPanel and use CSS to perform all the positioning/layout
I'm not 100% sure, but this feels like you have these options (and possibly others) because they offer benefits over each other in different circumstances, or because the GWT API has changed a lot and newer layout methods have been added over time.
If the former is the case, then security and performance are my only priorities, so I ask: is one method more performant and/or secure than the others? And if the latter is the case, then which method is GWT's newest and most encouraged? It would seem to me that the most control would be to leave everything for the CSS and not use Layout/LayoutPanel at all!
LayoutPanel uses absolute positioning, and it also provides size to its children. I like to use it for my outmost layout container, as it occupies the entire browser window and resizes its children when that browser window is resized.
For inside widgets (e.g. menus, main area) many people like to use VerticalPanel and HorizontalPanel (or, even LayoutPanel) for their simplicity. I avoid using these panels as they offer rigid, table-based layout. I prefer to use either HTMLPanel or FlowPanel, and achieve the desired layout through CSS.
Note that I would not use "old" or "new" attributes when discussing the pros and cons of different panels. They all translate into standard HTML. If you are comfortable with CSS (a lot of developers aren't), then you should use CSS as much as possible, because this is what browsers are optimized to do, and because you can build more fluid, consistent and future-proof (i.e. much easier to change) layouts with it.
What kind of app are you building?
Do you need 'user-positioned splitters' between panels?
Do you need separate scrolling panels?
If not, stick with CSS.
Start with an HTML/CSS mockup and then convert that to a GWT UiBinder file. Particularly when it comes to responsive web design, you can get a HUGE HEAD START by starting with an off-the-shelf CSS framework like Twitter Bootstrap.
what is the best way to have JFrames, JDialogs, etc that derive from a common parent but differ some, to be able to have the common parts update automatically when the parent does, but also have new components which are still easily modified in a GUI builder.
One approach I have used before is having placeholder JPanels that populate with existing isolated components at runtime, but I suspect that this is not the best way.
Example frame visual inheritence:
Don't use a GUIBuilder unless you creating some sort of prototype or other throw away code.
Have the components that need to update automatically setup as listeners for some sort of change event. Once an update is needed fire of an "Event" to each listener.