我在哪里将我的应用程序的所有“胆量”放在Vaadin应用程序中?继续添加“MyUI”课程?

时间:2016-05-14 05:29:13

标签: java layout vaadin vaadin7

我已经成功启动了第一个Vaadin 7应用程序,并由Maven archetype为我创建。此应用程序的模板显示了窗口小部件的布局,窗口小部件和业务逻辑(单击按钮),所有这些都在MyUI类中定义。

我从哪里开始?我是否只是继续在MyUI添加内容,还是有更好的方法来构建我的应用程序?

以下是Maven原型给我的MyUI的Java源代码。

package com.example.vaadinlayoutsexample;

import javax.servlet.annotation.WebServlet;

import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.annotations.Widgetset;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.Button;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

/**
 * This UI is the application entry point. A UI may either represent a browser window 
 * (or tab) or some part of a html page where a Vaadin application is embedded.
 * <p>
 * The UI is initialized using {@link #init(VaadinRequest)}. This method is intended to be 
 * overridden to add component to the user interface and initialize non-component functionality.
 */
@Theme("mytheme")
@Widgetset("com.example.vaadinlayoutsexample.MyAppWidgetset")
public class MyUI extends UI {

    @Override
    protected void init(VaadinRequest vaadinRequest) {
        final VerticalLayout layout = new VerticalLayout();

        final TextField name = new TextField();
        name.setCaption("Type your name here:");

        Button button = new Button("Click Me");
        button.addClickListener( e -> {
            layout.addComponent(new Label("Thanks " + name.getValue() 
                    + ", it works!"));
        });

        layout.addComponents(name, button);
        layout.setMargin(true);
        layout.setSpacing(true);

        setContent(layout);
    }

    @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
    @VaadinServletConfiguration(ui = MyUI.class, productionMode = false)
    public static class MyUIServlet extends VaadinServlet {
    }
}

app运行的屏幕截图。

screen shot of Vaadin app template running in a web browser window

2 个答案:

答案 0 :(得分:5)

当您的应用开始拥有更多观看次数时,您应该至少开始使用NavigatorViewProvider。这两个类都在Vaadin框架中。

将在Navigator类中创建MyUI对象。每个视图都实现了View接口,对于每个视图,您也可以拥有一个演示者(虽然这不是Vaadin概念)。

自定义ViewChangeListener以及NavigationStateManager也可能有用。

有关详细信息,请参阅https://vaadin.com/docs/-/part/framework/advanced/advanced-navigator.html。我也使用了“基础应用程序”,它同时使用MVP和DAO模式,你可以在这里查看:https://github.com/nyg/vaadin-app-base

答案 1 :(得分:-1)

应用程序模板有目的地保持简洁,以便于新手阅读和理解。用户界面的所有“活动部分”都收集在一个类MyUI中。

MyUI添加越来越多的小部件和行为很快变得难以处理。有很多方法可以将你的应用分成不同的部分,因为Vaadin在这方面非常灵活。我将描述我自己的方法。

在实际工作中,我保持MyUI课程尽可能短。作为UI的子类,MyUI表示由以下任一项显示的内容的整个视口:

  • 网络浏览器的窗口或标签(使用Vaadin的常用方法)
  • Portlet视图的矩形(如果您的Vaadin应用嵌入网页中)

换句话说,UI类只是一个空白画布,它知道如何适应主机的矩形视口。 UI的工作是在主机视口和Vaadin内容之间进行调解。管理Vaadin内容的详细信息最好留给单独的对象,定义为Layout的子类。因此UI代码变得更简单,只需要处理一个或多个Layout子类对象。

例如,您可能会显示登录Layout。然后,如果用户成功进行身份验证,则会切换出Layout。它是您实例化不同Layout子类以显示应用程序主要内容的位置。您的MyUI代码会处理从LoginLayout布局对象最初切换到使用InvoiceListingLayout布局对象替换。

在启动新的Vaadin应用程序时,我要做的第一件事就是提取VerticalLayout和“Click Me”按钮的代码,然后将其移动到新的Java类文件中。新类是VerticalLayout的扩展,带有一个构造函数,用于建立字段,按钮和按钮的行为。

以下是该新类ClickMeLayout的源代码。真实世界的布局有更多的代码,所以我通常将构造函数方法分解为三个子程序:

  • configure()
    设置整体布局的属性,例如调用setSpacingsetMargins
  • widgets()
    确定要在此布局中显示的每个小部件。我几乎总是将新的小部件作为私有成员变量分配给类,而不是像Maven生成的原始应用程序模板代码中看到的局部变量。
  • arrange()
    按照特定的顺序和排列将小部件添加到布局中。通常意味着创建嵌套布局作为小部件的子分组。

我还明确了this.语法,我自己的偏好。

以下是新课程ClickMeLayout.java

package com.example.vaadinlayoutsexample;

import com.vaadin.ui.Button;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;

/**
 *
 * @author Basil Bourque. Use freely, but only at your own risk entirely.
 */
public class ClickMeLayout extends VerticalLayout {

    private TextField name = null;
    private Button button = null;

    public ClickMeLayout () {
        this.configure ();
        this.widgets ();
        this.arrange ();
    }

    private void configure () {
        this.setMargin ( true );
        this.setSpacing ( true );
    }

    private void widgets () {

        // “Name” field
        this.name = new TextField ();
        this.name.setCaption ( "Type your name here:" );

        // “Click Me” button
        this.button = new Button ( "Click Me" );
        this.button.addClickListener ( e -> {
            this.addComponent ( new Label ( "Thanks " + this.name.getValue () + ", it works!" ) );
        } );

    }

    private void arrange () {
        this.addComponent ( this.name );
        this.addComponent ( this.button );
    }

}

建立这个班级后,我们可以回去缩短MyUI班级。 MyUI::init方法缩小为一行代码。

@Override
protected void init ( VaadinRequest vaadinRequest ) {
    this.setContent ( new ClickMeLayout () );
}

确保一切正常。在IDE中进行清理和构建。运行应用程序以查看它是否像最初一样工作。

继续构建您的真实应用。复制粘贴ClickMeLayout.java代码,创建新类并粘贴以用作原型。开始添加小部件以构建新的Layout。返回MyUI以使用new ClickMeLayout()注释掉该行,复制粘贴该行以复制它,并更改副本以调用新的布局类而不是ClickMeLayout

@Override
protected void init ( VaadinRequest vaadinRequest ) {
    // this.setContent ( new ClickMeLayout () );
    this.setContent ( new InvoiceListingLayout () );
}

我建议将ClickMeLayout永久保持在原始状态。我发现这是一个方便的理智检查。最终,当您的应用程序似乎变得混乱时,您可能无法确定问题是您自己的代码还是您的IDE,Web容器(Tomcat,Jetty等),您的Web浏览器或谁知道什么的一些故障。在这种情况下,您可以返回到MyUI方法,禁用对布局的调用,重新启用调用new ClickMeLayout()的行,执行清理和重建,然后运行应用程序。如果成功运行,您就会知道代码中存在错误。

顺便说一句,如果在addClickListener行中看到的新lambda语法会抛弃你,那么这里是使用旧Java语法作为匿名内部类的等效代码。

this.button.addClickListener ( new Button.ClickListener () {
    @Override
    public void buttonClick ( Button.ClickEvent e ) {
        ClickMeLayout.this.addComponent ( new Label ( "Thanks" + ClickMeLayout.this.name.getValue () + ", it works!" ) );
    }
} );