Почему vaadin дублирует вызов методов View?

Класс навигатора:

@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);
    }
}

Основной вид:

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);
            }
        });
    }
}

Реализация моего представления:

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);
            }
        });
    }
}

Приложение запускается из класса NavigatorUI, а затем переходит к MainView. Я перехожу к CreateQuestionsPoolView. Когда я вызываю любой метод представления, вызов дублируется. Я новичок в Ваадин и не могу понять причину.

Ваадин 7.0.5, Стеклянная рыбка 4


person user2966560    schedule 25.01.2014    source источник


Ответы (1)


Если вы добавите прослушиватель кликов в метод ввода, новый прослушиватель будет добавляться каждый раз, когда вы входите в представление. Таким образом, входя в представление во второй раз, когда вы нажимаете кнопку openCreateQuestionPoolViewButton, у вас есть два подключенных слушателя, и это действие запускается дважды.

Вы можете рассмотреть возможность использования MVC и шины событий, которые позволят вам сохранить навигатор в одном презентере.

person dzezzz    schedule 28.01.2014