So I'm trying to determine/remember what type of interface/abstract I have to use to get this layout to do what I want. I have two types of objects:
Widget and ComboWidget. I want both of these to be implemented in other classes. As the name suggests, ComboWidget is a base class that will be comprised of multiple Widget objects. I also want to have some boilerplate functionality such as addWidget(), removeWidget(), listWigets(), etc that will be applied to all items that implement ComboWidget.
Widget itself will do the same as it will be implemented by specific instances of widgets (A button widget, a fillbar widget etc).
I want to be able to have a panel or table that the user can add any widget or combo widget. So for said panel I want to generically refer to the Widget or ComboWidget as just Widget class and it will allow either or, in addition to any other object that implements those. What is the best way to accomplish this?
Best way to explain this is a drawing of sorts:
Widget
|_ ComboWidget
|_ TableComboWidget
|_ BoomHeightComboWidget
|_ ButtonWidget
|_ FillBarWiget
|_ TextWidget
I want to be able to make a function that says addWidget(Widget) and any of the above can be placed as an argument. (Except Widget and ComboWidget themselves as they will likely be the interface/abstracts)
What you have just described seems a lot like a Composite Pattern
And I don't see anything wrong with your class layout.
Your addWigget method should work just as you described it.
Study the Java AWT class hierarchy. It has the structure that you are looking for - the Component class serves as the base class of every AWT component, and Container is the equivalent of your ComboWidget.
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.
Greetings fellow Stackoverflownians!
I am building an Eclipse RCP application, and have come across an issue:
I want to set a tooltip text on a TreeItem, but this class does not inherit Control, which is the class that has the setTooltipText
EDIT: It seems that jface is supposed to take care of this seamlessly, through a LabelProvider.
I am using a ColumnLabelProvider with getToolTipText method on each column of a complex TreeViewer, but it isn't working. I wonder why...
The probleme here is that you use the SWT-Tree.
You should use a TreeViewer (JFace) which wraps the tree and gives you more sophisticated options.
Inside the label provider of the TreeViewer, you can define your tooltips.
Learn more about viewers here and here
An code example (tool tip) is here
I strongly recommend you to use the viewers!
With TreeViewer use
ColumnViewerToolTipSupport.enableFor(viewer);
Use a label provider derived for CellLabelProvider or one of it subclasses and override getToolTipText (there are also several other methods to control the font, time out and the like).
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.
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