GWT Compsite's initWidget not applicable for DivElement - java

I'm implementing MVP in my first GWT app using the recommended API from their docs, and admittedly, am doing some cargo cult programming while scrambling to learn/understand the API:
public class DefaultSignInView extends Composite implements SignInView {
private static DefaultSignInViewUiBinder uiBinder = GWT
.create(DefaultSignInViewUiBinder.class);
public DefaultSignInView() {
// ERROR: The method initWidget(Widget) in the type Composite is not applicable
// for the arguments (DivElement)
initWidget(uiBinder.createAndBindUi(this));
}
// Extends the UiBinder interface for this particular view.
interface DefaultSignInViewUiBinder extends UiBinder<DivElement, DefaultSignInView> {
// No-op.
}
}
In the above code snippet, the call to initWidget is a syntax/compiler error:
The method initWidget(Widget) in the type Composite is not applicable for the arguments (DivElement).
Now in the documentation (linked above) they show that you should extend UiBinder without the generic arguments. But I've also seen examples that use the generics, and again, cargo culting it, I borrowed from another example that used DivElement as the first argument. So, a few questions:
Why am I getting this syntax error?
What can I change DivElement to (or what else would I have to change) to correct it, besides removing the generic arguments? And if the generic arguments are deprecated or are truly no longer used, can someone explain why? In that case I'll just #SuppressWarnings.
Would someone provide a clear, layman's explanation of what the code is doing here? I hate cargo culting my code.

I sincerely think you are looking in the wrong place. Try this here. Most of it is explained in the docs, still i will try to highlight a few points,
What you are trying to do is very simple example of a UiBinder template that contains no widgets, only HTML.
So not being a widget, you cannot add it to a panel as a widget, instead you need to do a direct DOM manipulation.
I am adding a my sample code below
public class ImageViewer implements EntryPoint
{
#Override
public void onModuleLoad()
{
SampleUI sampleUI = new SampleUI();
sampleUI.setNameSpan(" Trying it out!!");
Document.get().getBody().appendChild(sampleUI.getElement());
}
}
SampleUI ui-binder
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder">
<ui:style>
.important {
font-weight: bold;
}
</ui:style>
<div>
Hello,
<span class="{style.important}" ui:field="nameSpan" />
</div>
</ui:UiBinder>
SampleUI java
public class SampleUI extends UIObject
{
private static SampleUIUiBinder uiBinder = GWT.create(SampleUIUiBinder.class);
interface SampleUIUiBinder extends UiBinder<DivElement, SampleUI>
{
}
private DivElement root;
#UiField
SpanElement nameSpan;
public SampleUI()
{
setElement(uiBinder.createAndBindUi(this));
}
public DivElement getRoot()
{
return root;
}
public void setNameSpan(String firstName)
{
nameSpan.setInnerText(firstName);
}
}

Related

Design pattern to enrich a class with new features [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have implemented a series of classes to manage search / detail page with JSF and PrimeFaces.
More in detail, I've created an abstract class SearchDetailView<C extends BaseView, M> in order to centralize common functionality for Search/Detail page.
In short, I've a class MyView that extends the base SearchDetailView.
Now I'd like to add another behavior to MyView, that is Confirm Dialog.
I'm wondering what design pattern I have to use? I was going to use the design pattern Decorator, but I don't need to add new behaviors at runtime, but I've already know what behaviors MyView needs.
I can't extends two classes (obviously), but I didn't like to have many combinations of "base" classes. I'd like to create a second abstract class like ConfirmDialogDecorator in order to add "programmatically" the extra functionality.
So, I ask you which design pattern add behavior to a class?
Actually my code is like the following:
public abstract class SearchDetailView<C extends BaseController, M> extends BaseView {
[...]
}
public abstract class ConfirmDialogDecorator<C extends BaseController, M> extends SearchDetailView<C, M> {
public void showDialog(final String message) { [...] }
}
public class MyView extends ConfirmDialogDecorator<MyController, MyModel> {
[...]
}
But I'd like to separate ConfirmDialogDecorator from SearchDetailView.
Any idea? Thanks.
UPDATE:
As suggested in the two answers I used the Java 8 default methods (Mixin pattern?):
public interface ConfirmDialog {
Dialog dialog = new Dialog();
default public String getConfirmMessage() {
return "Do you confirm?";
}
default String getWidgetVar() {
return "confirmDialog";
}
public void onConfirm();
default void showDialog(final String message) {
dialog.setWidgetVar(this.getWidgetVar());
dialog.setMessage(message);
dialog.showDialog(message);
}
class Dialog {
private String message;
private String widgetVar;
String getMessage() {
return message;
}
void setMessage(final String message) {
this.message = message;
}
public String getWidgetVar() {
return widgetVar;
}
public void setWidgetVar(final String widgetVar) {
this.widgetVar = widgetVar;
}
void showDialog(final String message) {
final PrimeFaces current = PrimeFaces.current();
current.executeScript("PF('" + this.widgetVar + "').show();");
}
}
}
public class MyView extends SearchDetailView<MyController, MyModel>
implements ConfirmDialog {
public void onSave() {
if(!this.someCheck()) {
this.showDialog("Are you really sure?");
} else {
this.save();
}
}
#Override
public void onConfirm() {
this.save();
}
public void save() {
// The save
}
}
In the xhtml:
<p:confirmDialog widgetVar="confirmDialog" global="true">
<h:outputText value="#{myView.confirmMessage}" />
<p:commandButton value="Yes" type="button" styleClass="ui-confirmdialog-yes" icon="pi pi-check" />
<p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="pi pi-times" />
</p:confirmDialog>
I was going to use the design pattern Decorator, but I don't need to
add new behaviors at runtime, but I've already know what behaviors
MyView needs.
and then
I'd like to create a second abstract class like ConfirmDialogDecorator
in order to add "dynamically" the extra functionality.
Don't you say a thing and its contrary ?
The fact that you know decorating possibilities at compile time doesn't mean that the pattern is not adapted.
But I'd like to separate ConfirmDialogDecorator from SearchDetailView.
Decorator is also a alternative to subclassing and avoid classes hierarchies.
Using the pattern by introducing a decorator interface is probably a right way for your requirement.
As alternative Java 8 introduced the notion of default methods in interfaces that allows to add behaviors to classes implementing it.
In a some way, we can consider it as a way to decorate statically classes with additional behaviors without subclassing. Note that as interfaces cannot define instance fields, default methods cannot use it either. So you should consider this alternative according to this constraint.
Usually to add functionality to a class without inheritance be used mixim/trait conception.
You can use default methods or aspect-objected programming in Java to the implementation of this conception

Passing superclasses into a method where a subclass is needed

Ok, while I tried to find a title that explains the problem I probably have to expand on it.
Recently I implemented a small program that will be used to control a tape library. Knowing it had to work with multiple different types of tape library so the following design was developed.
interface Tapelibrary<T extends TapeDrive> {
List<T> getListofDrives();
void doSomethingWithDrive(T d);
}
class SpecificTapeLibrary implements Tapelibrary<HPDrive> {
private List<HPDrive> driveList;
SpecificTapeLibrary() {
driveList.add(new HPDrive());
driveList.add(new HPDrive());
driveList.add(new HPDrive());
}
#Override
public List<HPDrive> getListofDrives() {
return driveList;
}
#Override
public void doSomethingWithDrive(HPDrive d) {
d.doSomethingHPspecific();
}
}
abstract class TapeDrive {
void doSomething() {
}
}
class HPDrive extends TapeDrive {
void doSomethingHPspecific() {
}
}
The correct tape library is determined by a factory based on command line arguments.
public static void main(String[] args) {
Tapelibrary<? extends TapeDrive> t = new TapeLibraryFabric().get();
List<? extends TapeDrive> listOfDrives = t.getListofDrives();
// the user selects a drive by using a small UI or something
TapeDrive selectedDrive = listOfDrives.get(0);
t.doSomethingWithDrive(selectedDrive); // compiler error
}
This does make sense since the compiler would have to explicitly cast the supertype TapeDrive to the subtype HPDrive which is expected by the doSomethingWithDrive(HPDrive) methods in SpecificTapeLibrary
How would this be solved in a good oop way? I ended up not using generics and casting inside the doSomethingWithDrive method (as suggested here:How to Pass a Child Class into a method requiring Super Class as parameter). But that can't be the optimal solution.
While writing this post another solution popped into my head which is much cleaner. The DriveSelector class encapsulates the selection process.
class DriveSelector {
<T> T selectDrive(List<T> inputList) {
// give the user an UI or something to select a drive
return inputList.get(0);
}
}
// the tape library then uses the selector
public void doSomethingWithSelectedDrive(DriveSelector selector) {
HPDrive t = selector.selectDrive(driveList);
t.doSomethingHPspecific();
}
Any other ideas?
Do all of your work in a generic method:
static <T extends TapeDrive> void doStuff(Tapelibrary<T> t) {
List<T> listOfDrives = t.getListofDrives();
// the user selects a drive by using a small UI or something
T selectedDrive = listOfDrives.get(0);
t.doSomethingWithDrive(selectedDrive);
}
Then call this from your main method:
Tapelibrary<? extends TapeDrive> t = new TapeLibraryFabric().get();
doStuff(t);
Ideone demo
The way this works is that it removes all of the wildcards - the thing about wildcards is that the compiler treats every one as different, even if the values are derived from a single generic instance. By putting things into the generic method like this, you allow the compiler to know that all of the Ts are the same type - thus it can know that the calls are safe.

Java Inheritance - Building a BaseView for the MVP pattern

We are trying to implement the MVP pattern. Because it requires quite a lot of code just to have a functioning view, we try to use inheritance as much as possible. As I am pretty new to Java, I don't know exactly if I'm doing it right:
So, I started with a very simple Interface which all the views will implement (and the `getName`` method will be used for breadcrumb Feature):
public interface IView {
public String getName();
}
On top of that, I built a BaseView which will be used for most views:
public interface IBaseView extends IView {
public void addListener(IBaseViewListener l);
interface IBaseViewListener {
void viewEntered(Long id);
}
}
And the implementation
public class BaseView extends CustomComponent implements View, IBaseView{
private String name = "";
private List<IBaseViewListener> listeners;
public BaseView(String name) {
this.name = name;
listeners = new ArrayList<IBaseViewListener>();
buildLayout();
}
#Override
public void addListener(IBaseViewListener l) {
listeners.add(l);
}
protected void buildLayout() {
this.setId("base_view");
// initialize layout....
}
#Override
public void enter(ViewChangeEvent event) {
for (IBaseViewListener l : listeners) {
l.viewEntered(id);
}
}
#Override
public String getName() {
return name;
}
}
And last we have a ScaffoldingView which will be used for some views (mainly for mocking):
public interface IScaffoldingView extends IBaseView{
public void showTable(AbstractComponent t);
interface IScaffoldingViewListener extends IBaseViewListener {
void itemSelected(DataBaseObject selectedObject);
}
}
And the implementation:
public class ScaffoldingView extends BaseView implements IScaffoldingView{
private AbstractComponent table = null;
public ScaffoldingView(String name) {
super(name);
}
#Override
protected void buildLayout() {
// here is a lot more code...
}
public void showTable(AbstractComponent t) {
// here is a lot of code...
}
}
First of all:
- Does that approach make any sense? especially the access modifiers. I'm totally weak when it Comes to polymorphism :(
I am very unsure about the handling of the EventListeners. For example: In the constructor of the BaseView, I am implementing the addListener function.
Now, in the ScaffoldingView's, there will be a specialized IScaffoldingViewListener. Will the super class (BaseView) addListener() method be able to handle These IScaffoldingViewListeners?
edit: Sorry, I forgot to mention that View and CustomComponent are some classes of a 3rd Party Framework (Vaadin) which we use and which offer the enter Event in which we call the eventListeners (Presenter).
First, declaring an interface inside another interface is not quite clean, obscures the code quite a bit.
Second, about BaseView which extends CustomComponent, and implements IView and IBaseView, first a small detail, if it implements IBaseView, you do not need to implement IView, as IBaseView already extends IView, but the bigger issue i see is:
If you have a somewhere in some class, a method with an IBaseView as a parameter, but inside that function you expect to be able to use the overrided methods from CustomComponent, you won't be able to, you'll only have the methods declared on IBaseView.
If you wanted to use the CustomComponent methods, you'd had to do a cast inside that method, but that is not clean and a source of bugs, because if in the future, you add more classes that implement IBaseView but do not extend CustomComponent, that function will throw exceptions complaining about casting.
Also, about the ScaffoldingView, if you are going to use it only for mocking purposes in tests and you are extending the IBaseView behaviour, with more methods, if you test a method that has an IBaseView as parameter, you have the same exact situation as before, the method you are testing will not be aware of the IScaffoldingView declared methods, and then it won't use them, and your tests can't be trusted.
P.D.: if you are interested in learning about abstractions and inheritance design, i'd recomend you to check S.O.L.I.D. principles, there's a lot of literature in the web about those.
Edit: Response to your comment
First you need to ask yourself without thinking about internal details or implementations or testing or anything else, what are the behaviour my Views have? are they all behaving the same way? do i have different types of views or not really? Once you answer these questions and got an idea of what is going on, you'll have what it will need to design the interface hierarchy, and thats what is going to be exposed to the rest of the system.
You can (optionally) have abstract classes that derive from those interfaces, where you can provide some initialization, defaults, but, do not go further in offering more functionality than the interface offers, you can have some extra methods, but only for internal use.
And then you can derive the actual implementation of the views from the interface or the intermediate abstract classes if you have defined any.
Just think of this as a black box, in which the only thing you can see are the input and output interfaces, everything else that is going inside that box, the rest of the system doesn't and shouldn't need to know about.
Can't really give you specific solution because i'm not aware of the needs of your application.

Using concrete class from a abstract type variable

I'm sorry if this question has been asked already, I haven't found anything like my question yet...
I'm working/playing/learning to build up some kind of testing environment... Inside it, I'm building an Application Layer (a package of classes that are the virtual representation of the different pages/windows/forms) of an application. The simplified setup is the following:
public abstract class WebPage {
protected WebDriver driver;
protected WebElement getElement(By by){
WebElement element = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(by));
return element;
}
public void menuLogout(){
System.out.println("Logged out");
}
}
public class HomePage extends WebPage {
public ProfilePage ClickLinktoProfilePage(){
return new ProfilePage();
}
public DashBoardPage clickViewDashboard(){
return new DashBoardPage();
}
public String getTitle(){
return getElement(By.id("title")).getText();
}
}
public class ProfilePage extends WebPage {
public String getUsername(){
return getElement(By.id("name")).getText();
}
public String getEmail(){
return getElement(By.id("email")).getText();
}
public HomePage clickReturnToHomePage(){
return new HomePage();
}
}
public class DashBoardPage extends WebPage {
public String getcurrentPeriod(){
return getElement(By.id("name")).getText();
}
}
The idea behind this is that I wish my Test to hold only one current WebPage. I do not wish to create a new variable each time I change page.
I also do not want to be forced to know in advance which page I'm heading into. I want the application Layer to give me the flow of the Application. In the same way that when clicking a link, you are brought to the following page, I wish that when I click a link that brings me to another page, that method tells me what page I'm heading into.
(WebPage abstract class also exposes lots of shared methods between all concrete WebPages)
So my intended use was:
WebPage currentPage = new HomePage();
currentPage = currentPage.ClickLinktoProfilePage(); //currentPage = new ProfilePage();
System.out.println(currentPage.getUsername());
currentPage.menuLogout();
Sadly, this does not work, since the currentPage variable is typed as WebPage, it cannot see any of the concrete classes's methods. I find it logical and odd at the same time because I can ask "currentPage.getClass().getName();" and it'll return "packageName.ConcreteClassName".
For Typecasting to work, I would need to redefine the variable's type... (not sure if it's possible or even good to do).
So I know I can find the name of the class inside the variable, but I'm not sure where to go from there.
Anyone got a solution?
To clarify what Radiodef and I are saying in the comments here:
What you want is to define WebPage (your abstract API) in such a way that your concrete subclasses don't need to have public methods that aren't a part of that API.
For example, compare the java.util.List interface in the standard library. There are multiple implementations of this interface (ArrayList and LinkedList are the most well-known ones, but there are many others), but the majority of code that uses List doesn't need to care whether it's actually using an ArrayList or a LinkedList or something else, since all the operations that you need are exposed via the List interface.
You can do the same thing with your WebPage class. For example, you could define a series of "hooks" for different operations that you can do with a web page:
public abstract class WebPage {
// methods that each subclass needs to implement
protected abstract String renderBodyHtml();
public abstract String getNameToLinkTo();
// other methods that are common to every page
public final void serve(
HttpServletRequest request, HttpServletResponse response) {
// write the response, using the specific page's body HTML
response.getWriter().println(renderToBodyHtml());
}
}
And then your pages would implement that contract like so:
// Note: the class doesn't need to be public, since anybody that uses
// it can just declare their variable as type WebPage
class Page1 extends WebPage {
#Override protected String renderBodyHtml() {
return "<body>Hello world!</body>";
}
#Override public String getNameToLinkTo() {
return "Page1";
}
}
Then code that wants to work with a WebPage doesn't need to know that it's a Page1 (or any other page):
public static void printPageName(WebPage webPage) {
System.out.println(webPage.getNameToLinkTo());
}
Alternatively, like resueman says, you can just use the Page1, Page2, etc., types directly, using WebPage only for implementation inheritance, not API. This is fine as well -- the correct solution depends on how flexible (and complex) you want your code to be.

GWT uiBinder.createAndBindUi(this) help

I am new to Java GWT plugins.
In our code, we are using code like below,
In test1.java
public class RowResults extends Composite
{
#UiField VerticalPanel vpnlWidgets;
public RowResults()
{
uiBinder.createAndBindUi(this));
getRows();
}
private void getRows()
{
for(RowDetails obj: RowDetailsArray)
{
RowWidget row= new RowWidget(obj);
vpnlWidgets.add(row);
}
}
}
In test2.java
public RowWidget(RowDetails rowObj)
{
uiBinder.createAndBindUi(this);
this.Row = rowObj;
}
I have posted here some necessary code. In this code, if I have 10 elements in RowDetailsArray, then for each elements createAndBindUi is called. It seems somewhat slow also.
Is there any way to call uiBinder.createAndBindUi(this); function one time and use that for all the 10 elements.
Also, what will happen while calling createAndBindUi(this). Whether it convert ui.xml file to class file or some thing else.
Pls Correct me if I am wrong.,
Thanks in Advance.
I guess it depends on how complicated your RowWidget is. If it has no special styling, I would suggest to use a FlexTable instead and just insert rows in it. It is quite optimized.
Use This Code Format.
public class RowResults extends Composite{
private static RowResultsUiBinder uiBinder = GWT.create(RowResultsUiBinder.class);
interface RowResultsUiBinder extends UiBinder<Widget, RowResults> {}
public RowResults(){
initWidget( uiBinder.createAndBindUi( this ) );
// put all your code here if you do not have any other constructor if you have put
//the above line in that constructor in the begning.
}

Categories

Resources