Question

Navigator class:

@CDIUI
@Title("RUT — Remote University Tool")
public class NavigatorUI extends UI {

    public static final String MAINVIEW = MainView.NAME;

    @EJB
    private TestCRUDService testCRUDService;
    @EJB
    private DisciplineService disciplineService;

    @Override
    protected void init(VaadinRequest request) {
        CreateQuestionsPoolView createQuestionsPoolView = new CreateQuestionsPoolView();
        createQuestionsPoolView.setTestCRUDService(testCRUDService);
        createQuestionsPoolView.setDisciplineService(disciplineService);

        MainView mainView = new MainView();

        Navigator navigator = new Navigator(this, this);
        navigator.addView(CreateQuestionsPoolView.NAME, createQuestionsPoolView);
        navigator.addView(MainView.NAME, mainView);

        navigator.navigateTo(MAINVIEW);
    }
}

MainView:

public class MainView extends VerticalLayout implements View {

    public static final String NAME = "main";

    private Button openCreateQuestionPoolViewButton = new Button("Создать тестовое задание");

    @Override
    public void enter(ViewChangeListener.ViewChangeEvent event) {
        addComponent(openCreateQuestionPoolViewButton);
        final Navigator NAVIGATOR = event.getNavigator();

        openCreateQuestionPoolViewButton.addClickListener(new Button.ClickListener() {
            @Override
            public void buttonClick(Button.ClickEvent event) {
                NAVIGATOR.navigateTo(CreateQuestionsPoolView.NAME);
            }
        });
    }
}

My View implementation:

public class CreateQuestionsPoolView extends VerticalLayout implements View {

    public static final String NAME = "test-creation";
    private Logger logger = Logger.getLogger(CreateQuestionsPoolView.class.getName());

    // ------------ main layout
    private TextField poolThemeField = new TextField("Тема");
    private TextField branchIdField = new TextField("Группа");
    private TextField disciplineField = new TextField("Дисциплина");

    private Button addQuestionButton = new Button("Добавить вопрос");
    private Button exportPoolButton = new Button("Экспортировать вопросы");
    private Button createQuestionsPoolButton = new Button("Создать новый тест");
    private Button saveQuestionsPoolButton = new Button("Сохранить тест");
    private Button openMainUIButton = new Button("Вернуться на стартовую страницу");

    // ------------ question layout
    private Layout questionLayout;
    private TextArea questionTitle = new TextArea("Вопрос");
    private TextArea[] answers = {
            new TextArea("Вариант ответа 1"),
            new TextArea("Вариант ответа 2"),
            new TextArea("Вариант ответа 3"),
            new TextArea("Вариант ответа 4")
    };
    private CheckBox[] isCorrectAnswerCheckboxes = {
            new CheckBox("Правильный"),
            new CheckBox("Правильный"),
            new CheckBox("Правильный"),
            new CheckBox("Правильный")
    };

    private Button saveQuestionButton = new Button("Сохранить вопрос");

    // ------------ download layout
    private Layout downloadLayout;
    private Button downloadButton = new Button("Скачать");

    // ------------ shared data
    private QuestionsPool questionsPool;
    private Navigator navigator;
    private TestCRUDService testCRUDService;
    private DisciplineService disciplineService;

    @Override
    public void enter(ViewChangeListener.ViewChangeEvent event) {
        logger.info("View will be initialized now");
        initMainLayout();
        initQuestionLayout();
        initDownloadLayout();

        navigator = event.getNavigator();
    }

    public void setTestCRUDService(TestCRUDService testCRUDService) {
        logger.info("TestCRUDService set up");
        this.testCRUDService = testCRUDService;
    }

    public TestCRUDService getTestCRUDService() {
        logger.info("TestCRUDService requested");
        return testCRUDService;
    }

    public void setDisciplineService(DisciplineService disciplineService) {
        logger.info("disciplineService set up");
        this.disciplineService = disciplineService;
    }

    public DisciplineService getDisciplineService() {
        logger.info("disciplineService requested");
        return disciplineService;
    }

    private void initDownloadLayout() {
        logger.info("Download layout initialization");
        downloadLayout = new GridLayout();
        downloadLayout.setVisible(false);
        downloadLayout.addComponent(downloadButton);
        addComponent(downloadLayout);
    }

    private void initQuestionLayout() {
        logger.info("Question layout initialization");
        questionLayout = new GridLayout();
        questionLayout.setSizeFull();
        questionLayout.setVisible(false);
        questionLayout.addComponent(questionTitle);
        questionTitle.setWidth("100%");
        for (int i = 0; i < answers.length; i++) {
            HorizontalLayout horizontalLayout = new HorizontalLayout();
            horizontalLayout.addComponent(answers[i]);
            horizontalLayout.addComponent(isCorrectAnswerCheckboxes[i]);
            horizontalLayout.setWidth("100%");
            horizontalLayout.setHeight("20%");
            questionLayout.addComponent(horizontalLayout);

            answers[i].setWidth("90%");
            answers[i].setHeight("100%");
        }
        questionLayout.addComponent(saveQuestionButton);

        saveQuestionButton.addClickListener(new Button.ClickListener() {
            @Override
            public void buttonClick(Button.ClickEvent event) {
                Question question = new Question(questionTitle.getValue());
                for (int i = 0; i < answers.length; i++) {
                    question.getAnswers().put(
                            new Answer(answers[i].getValue()), isCorrectAnswerCheckboxes[i].getValue()
                    );
                }
                questionsPool.getQuestions().add(question);
                Notification.show("Вопрос сохранен", Notification.Type.TRAY_NOTIFICATION);

                questionLayout.setVisible(false);
            }
        });
        addComponent(questionLayout);
    }

    private void initMainLayout() {
        logger.info("Main layout initialization");
        setWidth("100%");
        addComponent(poolThemeField);
        addComponent(branchIdField);
        addComponent(disciplineField);

        HorizontalLayout buttonsLayout = new HorizontalLayout();
        buttonsLayout.addComponent(addQuestionButton);
        buttonsLayout.addComponent(exportPoolButton);
        buttonsLayout.addComponent(createQuestionsPoolButton);
        buttonsLayout.addComponent(saveQuestionsPoolButton);
        buttonsLayout.addComponent(openMainUIButton);

        addComponent(buttonsLayout);

        addQuestionButton.setVisible(false);
        exportPoolButton.setVisible(false);

        addQuestionButton.addClickListener(new Button.ClickListener() {
            @Override
            public void buttonClick(Button.ClickEvent event) {
                logger.info("Add question button pressed");
                for (int i = 0; i < answers.length; i++) {
                    answers[i].setValue("");
                    isCorrectAnswerCheckboxes[i].setValue(false);
                }
                questionTitle.setValue("");

                questionLayout.setVisible(true);
            }
        });

        exportPoolButton.addClickListener(new Button.ClickListener() {
            @Override
            public void buttonClick(Button.ClickEvent event) {
                logger.info("Export pool button pressed");
                String serializedPool = JsonTransformer.toString(questionsPool);
                downloadLayout.setVisible(true);

                FileDownloader fileDownloader = new FileDownloader(createResource(serializedPool));
                fileDownloader.extend(downloadButton);
            }
        });

        createQuestionsPoolButton.addClickListener(new Button.ClickListener() {
            @Override
            public void buttonClick(Button.ClickEvent event) {
                logger.info("Create pool button pressed");
                questionsPool = new QuestionsPool(poolThemeField.getValue());
                questionsPool.setBranchId(Integer.valueOf(branchIdField.getValue()));
                questionsPool.setQuestions(new ArrayList<Question>());

                addQuestionButton.setVisible(true);
                exportPoolButton.setVisible(true);
            }
        });

        saveQuestionButton.addClickListener(new Button.ClickListener() {
            @Override
            public void buttonClick(Button.ClickEvent event) {
                logger.info("Save question button pressed");
                testCRUDService.addQuestionsPool(
                        questionsPool, disciplineService.getDisciplineByName(disciplineField.getValue()));
            }
        });

        openMainUIButton.addClickListener(new Button.ClickListener() {
            @Override
            public void buttonClick(Button.ClickEvent event) {
                logger.info("Back to main UI button pressed");
                navigator.navigateTo(NavigatorUI.MAINVIEW);
            }
        });
    }
}

Application starts from NavigatorUI class and then navigates to MainView. I navigating to CreateQuestionsPoolView. When I invoking any method of the View, invocation duplicates. I'm new to Vaadin and can't understand the reason.

Vaadin 7.0.5, Glassfish 4

Was it helpful?

Solution

If you add click listener in enter method then new listener is added every time you enter the view. So entering the view for the second time, when you click your openCreateQuestionPoolViewButton you have two listeners attached and it's action is fired twice.

You could consider using MVC and event bus which would let you keep your navigator in one presenter.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top