菜单项和模态窗口每次打开时都会相乘

时间:2014-12-01 07:49:27

标签: java vaadin

我创建了一个vaadin表。当我right-click时,它显示带有+New...文本的上下文菜单,当我点击它时 - 它显示带有两个表的模态窗口。每张桌子都有相同的功能。

enter image description here

问题在于,每次打开和关闭模态窗口时,它都会在模态表上添加上下文菜单项的重复项(在主页面上它可以正常工作)。此外 - 当我点击模态表上下文菜单时,它会添加几个模态窗口(例如,如果我打开窗口5次 - 它会为点击的模态上下文菜单添加5个上下文菜单项和5个模态窗口)

enter image description here

返回一个项目的唯一方法 - 重启整个应用程序。 有什么问题?

我的每张桌子都是这样的

@Component("taskTable")
@Scope("prototype")
public class TaskTable extends AbstractObjectTable {

    @Autowired
    private TaskService taskService;

    @Autowired
    private NewTaskWindow taskWindow;

    @Autowired
    private ShowTaskDetailsWindow detailsWindow;

    private Action[] action = new Action[] { new Action("+New...") };

    @Override
    public Table createTable() {

        caption = "Tasks";
        headers = new String[] { "Description", "Project", "Status", "Weight", "Developer", "ID" };
        this.addActionHandler(new Handler() {

            @Override
            public Action[] getActions(Object target, Object sender) {
                return action;
            }

            @Override
            public void handleAction(Action action, Object sender, Object target) {
                switch(action.getCaption()) {
                    case "+New...": {
                        PmcUi.getCurrent().addWindow(taskWindow.createWindow());
                        break;
                    }
                }
                //what to do for action
            }

        });

        this.addItemClickListener(new ItemClickListener(){

            @Override
            public void itemClick(ItemClickEvent event) {
                if (event.isDoubleClick()) {
                    PmcUi.getCurrent().addWindow(detailsWindow.createWindow());
                }
                return;
            }

        });
        return super.createTable();
    }

    @Override
    protected IndexedContainer projectDatasource() {
        IndexedContainer indexedContainer = new IndexedContainer();

        for(String header: headers) {
            indexedContainer.addContainerProperty(header, String.class, "");
        }

        List<Task> tasks = taskService.findAllTasks();

        for(int i = 0; i < tasks.size(); i++) {
            Object id = indexedContainer.addItem();
            Task item = tasks.get(i);
            indexedContainer.getContainerProperty(id, headers[0]).setValue(item.getDescription());
            indexedContainer.getContainerProperty(id, headers[1]).setValue(item.getTaskProject());
            indexedContainer.getContainerProperty(id, headers[2]).setValue(item.getStatus());
            indexedContainer.getContainerProperty(id, headers[3]).setValue(item.getWeight());
            indexedContainer.getContainerProperty(id, headers[4]).setValue(item.getTaskDeveloper());
            indexedContainer.getContainerProperty(id, headers[5]).setValue(item.getTaskId());
        }

        return indexedContainer;
    }

}

AbstractObjectTable

public abstract class AbstractObjectTable extends Table {

    protected String caption;
    protected String[] headers = null;

    protected Table createTable() {
        this.setContainerDataSource(projectDatasource());
        this.setVisibleColumns(headers);
        this.setSelectable(true);
        this.setImmediate(true);

        return this;
    }

    protected abstract IndexedContainer projectDatasource();

}

我的+New...模态窗口与

类似
@Component("newTaskWindow")
public class NewTaskWindow {

    private Window createTaskWindow;

    @Autowired
    private TaskService taskService;

    public Window createWindow() {
        createTaskWindow = new Window("New Task");
        initWindow();
        fillWindow();

        return createTaskWindow;
    }

    private void initWindow() {
        createTaskWindow.setSizeUndefined();
        createTaskWindow.setResizable(false);
        createTaskWindow.setModal(true);
        createTaskWindow.addCloseListener(new CloseListener() {

            @Override
            public void windowClose(CloseEvent e) {
                Notification.show("Closed");
            }

        });
    }

    private void fillWindow() {
        final TextField taskDescription = new TextField("Description");
        final ComboBox taskProject = new ComboBox("Select project");
        final ComboBox taskDeveloper = new ComboBox("Select developer");
        final TextField taskWeight = new TextField("Task weight");
        final TextField taskStatus = new TextField("Task status");
        Button create = new Button("Create");
        create.addClickListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                Task task = new Task();
                task.setTaskId(UUID.randomUUID().toString());
                task.setStatus(taskStatus.getValue());
                task.setTaskDeveloper(taskDeveloper.getValue().toString());
                task.setTaskProject(taskProject.getValue().toString());
                task.setWeight(taskWeight.getValue());
                task.setDescription(taskDescription.getValue());

                taskService.insertTask(task);
                createTaskWindow.close();
            }
        });

        Button close = new Button("Cancel");
        close.addClickListener(new Button.ClickListener() {

            @Override
            public void buttonClick(ClickEvent event) {
                createTaskWindow.close();
            }

        });

        HorizontalLayout layout = new HorizontalLayout(create, close);
        FormLayout formLayout = new FormLayout(taskProject, taskDeveloper, taskWeight, taskStatus,
                taskDescription, layout);
        formLayout.setMargin(true);

        createTaskWindow.setContent(formLayout);
    }

}

我的details窗口也有类似的架构。

@Component("showTaskDetailsWindow")
public class ShowTaskDetailsWindow {

    private Window showDetailsWindow;

    @Autowired
    private TaskService taskService;

    public Window createWindow() {
        showDetailsWindow = new Window("Show details");
        initWindow();
        fillWindow();
        return showDetailsWindow;
    }

    private void initWindow() {
        showDetailsWindow.setSizeUndefined();
        showDetailsWindow.setResizable(false);
        showDetailsWindow.setModal(true);
        showDetailsWindow.addCloseListener(new CloseListener() {

            @Override
            public void windowClose(CloseEvent e) {
                Notification.show("Closed");
            }

        });
    }

    private void fillWindow() {
        final TextField taskDescription = new TextField("Description");
        final TextField taskProject = new TextField("Task project");
        final TextField taskDeveloper = new TextField("Task developer");
        final TextField taskWeight = new TextField("Task weight");
        final TextField taskStatus = new TextField("Task status");

        FormLayout formLayout = new FormLayout(taskProject, taskDeveloper, taskWeight, taskStatus, taskDescription);
        formLayout.setMargin(true);

        showDetailsWindow.setContent(formLayout);
    }

}

有什么问题?为什么它会不断增加?

2 个答案:

答案 0 :(得分:0)

问题是你的getActions实现

@Override
public Action[] getActions(Object target, Object sender) {
    return new Action[] { new Action("+New...")};
}

您应该创建一个“new Action(”+ New ...“)”项的实例,并将其存储在例如TaskTable对象中。 getActions(..)应该返回相同的实例。

如果您始终创建新操作,则只需将其添加到现有操作中。

答案 1 :(得分:0)

看起来createTable()类的TaskTable方法被调用的次数太多,但提供的代码并未显示该方法的调用位置。这会导致将多个操作处理程序和项目单击侦听器添加到表中。