Vaadin using multiple context menus

2019-07-31 07:04发布

问题:

Im trying to create a Table with Vaadin where you have different options in the context menu depending on if you have selected a single row or multiple rows.

It took me a while to do this but now i have a working solution. The problem is that is feel that its not good coding practice and I would gladly take any advice in how to perhaps split my "function" into smaller classes or functions. Could I perhaps create a standalone Action class?. Feel free to comment and advice and please do note that I just started with Vaadin =) !

          Table contactList = new Table("Test table");
 3        contactList.addListener(new Property.ValueChangeListener(){
 4            public void valueChange(ValueChangeEvent event){            
 5                Set<?> value = (Set<?>) event.getProperty().getValue();
 6                if(value == null || value.size() == 0){
 7                    getMainWindow().showNotification("NULL or 0");
 8                }else if(value.size() == 1){
 9                    contactList.removeAllActionHandlers();
10                    contactList.addActionHandler(new Action.Handler(){
11                        public Action[] getActions(Object target, Object sender){                           
12                            return ACTIONS_EDIT;                        
13                        }                        
14                        public void handleAction(Action action, Object sender, Object target){                               
15                            getMainWindow().showNotification("ACTION_EDIT");                               
16                        }
17                    });
18                }else{
19                    contactList.removeAllActionHandlers();
20                    contactList.addActionHandler(new Action.Handler(){
21                        public Action[] getActions(Object target, Object sender){                           
22                            return ACTIONS_EDIT_ALL;                        
23                        }                        
24                        public void handleAction(Action action, Object sender, Object target){                               
25                            getMainWindow().showNotification("ACTION_EDIT_ALL");                               
26                        }
27                    });       
28                }
29            }
30        });

Thx for any help! /Marthin

回答1:

To me this looks overly complicated.

Instead of changing action handlers, you could just check the number of selections in the handler. Something like:

 contactList.addActionHandler(new Action.Handler(){
      public Action[] getActions(Object target, Object sender){                           
           Set<?> value = (Set<?>) contactList.getValue();
           return (value == null || value.size() == 0) = ACTIONS_EDIT : ACTIONS_EDIT_ALL;                       
      }                    
      public void handleAction(Action action, Object sender, Object target){                               
           getMainWindow().showNotification("Action: " + action);                               
      }
 });

Did not test the code to see if it works. I suspect that you must set contactList.setImmediate(true) to ensure that a correct context menu is shown.



回答2:

So i broke down the anonymouse classes and made them to inner classes. There are also some new functionalities. All feedback is welcome ofcourse, hopfully this might help someone else to break free the anonymouse classes they like to use in Vaadin.

class ExtendedTableFieldFactory implements TableFieldFactory{
    private static final long serialVersionUID = 1L;

    public Field createField(Container container, Object itemId, Object propertyId, Component uiContext){
        if(selectedRows != null){
            if(selectedRows.contains(itemId)){              
                return new com.vaadin.ui.TextField();
            }
        }
        return null;
    }
}


/**
 * Event handling for the table.
 * If one or more rows has been selected we set the corresponding action.
 * The action repaints the context menu.
 */ 
class ExtendedValueChangeListener implements Property.ValueChangeListener
{
    private static final long serialVersionUID = 1L;

    @Override
    public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
        setEditable(false);
        selectedRows = (Set<T>) event.getProperty().getValue();


        if(selectedRows == null || selectedRows.size() == 0){
            extActionHandler.setCurrentAction(ACTIONS_EDIT);        
        }else if(selectedRows.size() == 1){
            extActionHandler.setCurrentAction(ACTIONS_EDIT);        
            requestRepaint();
        }else{
            if(extActionHandler.getCurrentAction() != ACTIONS_EDIT_ALL)
            {                   
                extActionHandler.setCurrentAction(ACTIONS_EDIT_ALL);
                requestRepaint();
            }
        }
    }       
}


/**
 * The action handler is the context menu in the table.
 * We have a handler that takes the appropriate action on events.
 */
class ExtendedActionHandler implements Action.Handler{
    private static final long serialVersionUID = 1L;
    private Action[] currentAction = null;

    @Override
    public Action[] getActions(Object target, Object sender) {          
        System.out.println("calling GETACTIONS!");
        return currentAction;
    }

    @Override
    public void handleAction(Action action, Object sender, Object target) {
        System.out.println("calling handleActions aciton: "+action);
        if(action == ACTION_EDIT_ALL_MODAL){
            if (subwindow != null && subwindow.getParent() != null) {
                subwindow.focus();                  
            } else {          
                subwindow = new Window("Edit contacts");
                subwindow.setModal(true);

                VerticalLayout layout = (VerticalLayout) subwindow.getContent();
                layout.setMargin(true);
                layout.setSpacing(true);

                T data = selectedRows.iterator().next();
                try {
                    T dataEmpty = (T) data.getClass().newInstance();                        
                    modalForm.setItemDataSource(new BeanItem<T>(dataEmpty));

                } catch (InstantiationException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }


                subwindow.addComponent(modalForm);
                subwindow.setWidth("720px");
                subwindow.center();                 
                getParent().getWindow().addWindow(subwindow);

                //getWindow().addWindow(subwindow);

            }
        }else{
            setEditable(true);
        }       

    }       
    public Action[] getCurrentAction() {
        return currentAction;
    }

    public void setCurrentAction(Action[] currentAction) {
        System.out.println("setting current action to: " + currentAction);
        this.currentAction = currentAction;

    }

}

Best Regards Marthin