Как изменить основной вид приложения Vaadin 7?

Я хочу написать приложение 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);
    }
}

person Mentiflectax    schedule 09.10.2013    source источник


Ответы (3)


На форуме Vaadin кто-то предложил использовать навигатор, который решил моя проблема.

person Mentiflectax    schedule 11.10.2013
comment
Можете ли вы поделиться здесь некоторым кодом, чтобы лучше ответить на свой вопрос для потомков? - person Basil Bourque; 11.06.2014

Я бы скорее подумал, что MainUI должен расширять HorizontalSplitPanel, а не пользовательский интерфейс. Для меня странная идея вставлять один пользовательский интерфейс в другой.

person michaldo    schedule 10.10.2013

Вы можете использовать @SpringUI для основного класса, который расширяет пользовательский интерфейс:

@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 и реализует представление Vaadin.

@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});
  }
  }
 }
person mari    schedule 04.03.2016
comment
Не могли бы вы уточнить свой ответ, добавив немного больше описания решения, которое вы предоставляете? - person abarisone; 04.03.2016