如何更改Vaadin 7应用程序的主视图?

时间:2013-10-09 11:22:30

标签: vaadin vaadin7

我想写一个Vaadin 7应用程序(参见下面的 MyVaadinUI ),它要求用户输入用户名和密码。

如果它们是正确的,则应出现另一个视图(请参阅下面的 MainUI )并占据整个区域(替换登录视图)。

我尝试在方法 MyVaadinUI.goToMainWindow 中实现此转换,但是我收到了错误

java.lang.RuntimeException: Component must be attached to a session when getConnectorId() is called for the first time
    at com.vaadin.server.AbstractClientConnector.getConnectorId(AbstractClientConnector.java:417)
    at com.vaadin.server.communication.ConnectorHierarchyWriter.write(ConnectorHierarchyWriter.java:67)
    at com.vaadin.server.communication.UidlWriter.write(UidlWriter.java:143)
    at com.vaadin.server.communication.UidlRequestHandler.writeUidl(UidlRequestHandler.java:149)
    at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:97)
    at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:37)
    at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1371)
    at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:238)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)

当我运行应用程序并按下按钮时。

我该如何解决?

@Theme("mytheme")
@SuppressWarnings("serial")
public class MyVaadinUI extends UI
{
    private TextField userNameTextField;
    private PasswordField passwordTextField;

    @WebServlet(value = "/*", asyncSupported = true)
    @VaadinServletConfiguration(productionMode = false, ui = MyVaadinUI.class, widgetset = "ru.mycompany.vaadin.demo.AppWidgetSet")
    public static class Servlet extends VaadinServlet {
    }

    @Override
    protected void init(VaadinRequest request) {
        final VerticalLayout layout = new VerticalLayout();
        layout.setMargin(true);
        setContent(layout);

        addUserNameTextField(layout);
        addPasswordTextField(layout);

        addButton(layout, request);
    }

    private void addPasswordTextField(Layout aLayout) {
        passwordTextField = new PasswordField("Пароль:");

        aLayout.addComponent(passwordTextField);

    }

    private void addUserNameTextField(final Layout aLayout) {
        userNameTextField = new TextField("Пользователь:");

        aLayout.addComponent(userNameTextField);
    }


    private void addButton(final Layout aParent, final VaadinRequest request) {
        final Button button = new Button("Войти");
        button.addClickListener(new Button.ClickListener() {
            public void buttonClick(Button.ClickEvent event) {
                final boolean credentialsCorrect = checkCredentials();

                if (credentialsCorrect) {
                    goToMainWindow(request);
                } else {
                    [...]
                }
            }
        });
        aParent.addComponent(button);
    }

    private void goToMainWindow(final VaadinRequest aRequest) {

        final MainUI mainUI = new MainUI();
        mainUI.init(aRequest);
        setContent(mainUI);
    }

}

@Theme("mytheme")
@SuppressWarnings("serial")
public class MainUI extends UI {
    @Override
    protected void init(final VaadinRequest vaadinRequest) {
        final HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();

        setContent(splitPanel);

        splitPanel.setSizeFull();
        splitPanel.setSplitPosition(200, Unit.PIXELS);

        final String[] tabLabels = new String[] {
                "Tree item 1",
                "Tree item 2"};

        final Tree tree = new Tree();

        for (int i=0; i < tabLabels.length; i++)
        {
            addTreeItem(tree, tabLabels[i]);
        }

        splitPanel.setFirstComponent(tree);
        splitPanel.setSecondComponent(new Label("Test"));
    }

    private void addTreeItem(final Tree aTree, final String aLabel) {
        aTree.addItem(aLabel);
    }
}

3 个答案:

答案 0 :(得分:7)

在Vaadin论坛上,有人建议使用navigator来解决我的问题。

答案 1 :(得分:2)

我宁愿认为MainUI应该扩展Horizo​​ntalSplitPanel,而不是UI。将一个UI插入另一个UI是一个奇怪的概念。

答案 2 :(得分:1)

您可以将@SpringUI用于扩展UI的主类:

@SpringUI
@Theme("mytheme")
@Widgetset("com.MyAppWidgetset")
@PreserveOnRefresh
public class MainUI extends UI {

  private static final long serialVersionUID = -8247521108438815011L;

  private static Locale locale = VaadinSession.getCurrent().getLocale();
  @Autowired
  private ToolBoxMessageSource messageSource;

  @Autowired
  private SpringViewProvider springViewProvider;

  public MainUI() {

  }

 //Initializes navigator with SpringViewProvider and add all existing 
 //and ui specific assigned views to navigator.

  @Override
  protected void init(VaadinRequest vaadinRequest) {
    Navigator navigator = new Navigator(this, this);
    // Adding springViewProvider for spring autowiring
    navigator.addProvider(springViewProvider);
    // Adding all views for navigation
    navigator.addView(LoginView.NAME, LoginView.class);
    navigator.addView(MainView.NAME, MainView.class);
    navigator.addView(MailToolView.NAME, MailToolView.class);
    navigator.addView(AdminView.NAME, AdminView.class);
    navigator.addView(EditRecipientView.NAME, EditRecipientView.class);
    navigator.addView(EditRecipientsView.NAME, EditRecipientsView.class);
    navigator.addView(ServerView.NAME, ServerView.class);
    navigator.addView(TestJobView.NAME, TestJobView.class);
    navigator.addView("", new LoginView());
    navigator.navigateTo(LoginView.NAME);
    navigator.setErrorView(LoginView.class);

  // security: if user changes view check if the user has the required rights
  navigator.addViewChangeListener(new ViewChangeListener() {
  private static final long serialVersionUID = 7330051193056583546L;

  @Override
  public boolean beforeViewChange(ViewChangeEvent event) {
    Toolbox toolbox = getSession().getAttribute(Toolbox.class);
    if (TbRightManagement.checkAccess(event.getNewView().getClass(), toolbox)) {
      return true;
    } else {
      if (toolbox != null) {
        TBNotification.show(messageSource.getMessage("access.denied.title", locale),
            messageSource.getMessage("access.denied.no_permissions.msg", locale),
            Type.ERROR_MESSAGE);
        navigator.navigateTo(MainView.NAME);
        return false;
      } else {
        TBNotification.show(messageSource.getMessage("access.denied.title", locale),
            messageSource.getMessage("access.denied.not_loggedin.msg", locale),
            Type.ERROR_MESSAGE);
        navigator.navigateTo(LoginView.NAME);
        return false;
      }
    }
  }

  @Override
  public void afterViewChange(ViewChangeEvent event) {}
});
}
}

对于其他视图,作为示例,EditRecipientsView应该是@SpringView,它扩展了Vaadin Designer并实现了Vaadin View。

@SpringView(name = EditRecipientsView.NAME)
@Theme("mytheme")
@TbRight(loggedIn = true, mailTool = true)
public class EditRecipientsView extends RecipientsDesign implements View {

private static final long serialVersionUID = 1L;
public static final String NAME = "editRecipients";

private static Locale locale = VaadinSession.getCurrent().getLocale();

private BeanItemContainer<Recipient> recipientContainer;

private Uploader uploader;

@Autowired
private ToolBoxMessageSource messageSource;

  public EditRecipientsView() {
  super();
  }
   //Initializes the ui components of the recipient view.
  @PostConstruct
  public void init() {
  btn_addRecipient.addClickListener(e ->   {   MainUI.getCurrent().getNavigator().navigateTo(EditRecipientView.NAME);});
  }
   //Handling data when entering this view.
   @Override
   public void enter(ViewChangeEvent event) {
   if (getSession().getAttribute(UIMailing.class) != null) {
    List<Recipient> recipientList =   getSession().getAttribute(UIMailing.class).getRecipients();
    if (recipientList != null) {
      recipientContainer.removeAllItems();
    } else {
      recipientList = new ArrayList<Recipient>();
    }
    recipientContainer.addAll(recipientList);
    recipient_table.sort(new Object[] {"foreName", "lastName"}, new boolean[]    {true, true});
  }
  }
 }