1. #1
    Sencha User
    Join Date
    Sep 2011
    Location
    Leipzig, Germany
    Posts
    75
    Vote Rating
    1
    A.Rothe is on a distinguished road

      0  

    Default MessageBox.QUESTION on Dialog

    MessageBox.QUESTION on Dialog


    Hi,

    how I can add an image like MessageBox.QUESTION to an existing instance of Dialog? I have to use Dialog, because I need as superclass Window and not Object.

    Is that possible?
    Thanks a lot
    Andre

  2. #2
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,731
    Vote Rating
    90
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default


    Why do you need superclass of Window and not Object? You should never add any Window or Dialog to another parent widget, so this really shouldn't be an issue. If you want to update the underlying widget, you can invoke messageBox.getDialog() to get a reference to that dialog.

    That said, the MessageBox makes a custom set of changes to the body of the dialog, which includes that icon. Note that unlike a Dialog or Window which have their icon next to the header, the MessageBox has a large icon in the body of the panel itself. The contents of the MessageBox.QUESTION string is a css class that can be applied to an element to make it draw the icon, but other dom structure details applied by the MessageBox may also be required. Look at MessageBox.getDialog() to see the complete details of how it customizes the dialog contents.

  3. #3
    Sencha User
    Join Date
    Sep 2011
    Location
    Leipzig, Germany
    Posts
    75
    Vote Rating
    1
    A.Rothe is on a distinguished road

      0  

    Default


    I work on a Desktop-based application, the window handling awaits always Window references to add and remove the windows on a central point. So I have to override all x-tool-close listener and also I have to set new listeners on every button of the dialogs.

    The simplest way is to use Dialog instead of MessageBox, because it is a Window subclass and I can remove the tools listener and override onButtonPressed() to generate events on my EventBus. That was the background of my question.

    I would like to use both, the icon on the head of the Dialog and the MessageBox icon next to the message.

    Yesterday I created a sub-class of MessageBox, which contains:

    Code:
        public abstract class AbstractMessageBox extends MessageBox {
    
        public void initButtons() {
            getDialog().setHideOnButtonClick(false);
    
            ButtonBar bar = getDialog().getButtonBar();
            for (Component c : bar.getItems()) {
                removeSelectionListener(c);
                c.addListener(Events.Select, getCloseButtonListener());
            }
    
            if (!isClosable()) {
                return;
            }
    
            getDialog().addListener(Events.Attach, getAttachListener()); 
        }
        }
    The removeSelection() method removes all listeners with class names starting with "com.extjs.gxt". These listeners are not defined by my own subclasses and hide the window automatically or do something other things. Then I install my own listener. The listener for the x-tool-close I have to remove later, because at creation time of the Dialog the tools are not initiated. So I use an Events.Attach listener.

    Code:
        private void removeSelectionListener(Component c) {
            List<Listener<? extends BaseEvent>> listenerList = new ArrayList<Listener<? extends BaseEvent>>(c.getListeners(Events.Select));
            for (Listener<? extends BaseEvent> listener : listenerList) {
                if (listener.getClass().getName().startsWith("com.extjs.gxt")) {
                    c.removeListener(Events.Select, listener);
                }
            }
        }
    
        private Listener<ComponentEvent> getCloseButtonListener() {
            return new Listener<ComponentEvent>() {
                @Override
                public void handleEvent(ComponentEvent ce) {
                    beforeHide();
                }
            };
        }
    
        public abstract void beforeHide();
    
        private Listener<BaseEvent> getAttachListener() {
            return new Listener<BaseEvent>() {
                @Override
                public void handleEvent(BaseEvent event) {
                    for (Component tool : getDialog().getHeader().getTools()) {
                        if (tool.el().hasStyleName("x-tool-close")) {
                            removeSelectionListener(tool);
                            tool.addListener(Events.Select, getCloseButtonListener());
                        }
                    }
                }
            };
        }
    beforeHide() must be overriden to send events on my EventBus. It is now possible to create a view class, which handles the MessageBox subclass as Window.

    Code:
    public abstract class AbstractMessageBoxView implements WindowView {
    
        private AbstractMessageBox box;
    
        public final Window getWindow() {
            if (box == null) {
                box = new AbstractMessageBox() {
                    @Override
                    public void beforeHide() {
                        getPresenter().beforeHide();
                    }
                };
                initMessageBox(box);
                box.initButtons();
                box.getDialog().addWindowListener(getShowWindowListener());
            }
            return box.getDialog();
        }
    
        private WindowListener getShowWindowListener() {
            return new WindowListener() {
                @Override
                public void windowShow(WindowEvent we) {
                    getPresenter().afterShow();
                }
            };
        }
    
        protected Button getButtonById(String id) {
            return ((Dialog) getWindow()).getButtonById(id);
        }
    
        protected abstract WindowPresenter getPresenter();
    
        protected abstract void initMessageBox(MessageBox box);
    }
    initMessageBox() can be used to define options for the MessageBox. This is very tricky, because some options must be set on the Dialog, some other on the MessageBox, to get an effect.

    Code:
        public class ConfirmDeleteView extends AbstractMessageBoxView {
    
        @Override
        protected void initMessageBox(MessageBox box) {
            box.setClosable(true);
            box.getDialog().setHeading(constants.confirmDeleteTitle());
            box.getDialog().setIcon(IconHelper.create(resources.menuitemIcon()));
    
            box.setIcon(MessageBox.QUESTION);
            box.getDialog().setButtons(Dialog.YESNO);
            box.getDialog().yesText = constants.confirmDeleteYes();
            box.getDialog().noText = constants.confirmDeleteNo();
            box.getDialog().setButtonAlign(HorizontalAlignment.RIGHT);
    
            box.getDialog().setModal(false);
            box.setMessage("ho-ho-ho");
    
            getButtonById(Dialog.YES).addSelectionListener(getYesButtonListener());
        }
        }
    The selection listener for Dialog.YES doesn't handle window actions, it is only there to get information about the pressed button and initiated the business logic for the button on the presenter class.

    The WindowView interface defines getWindow() and so it is possible to call the method on a central point (after a specifc event on the EventBus). It is similar to your DesktopApp example, I have a class, which handles desktop specific things like start menu, shortcuts and also the windows.

    Code:
        public void addApplication(WindowView view) {
            Window window = view.getWindow();
            if (!getDesktop().getWindows().contains(window)) {
                getDesktop().addWindow(window);
            }
            if ((window != null) && (!window.isVisible())) {
                window.show();
            } else {
                window.toFront();
            }
        }
        
        public void removeApplication(WindowView view) {
            Window window = view.getWindow();
            if (getDesktop().getWindows().contains(window)) {
                window.hide();
                getDesktop().removeWindow(window);
            }
        }
    It is not possible to override the Dialog within the MessageBox with an own class. This would simplify some parts of the code (i.e. I could override Dialog.initTools()). I could also copy the whole code of MessageBox.getDialog() and rewrite it on a subclass, but the member field "dialog" is private, so I can not replace the right dialog.

    Last but not least, I could use Dialog instead of MessageBox, but (and this was my first idea) I have to recreate the code, which generates the MessageBox icon within a simple Dialog to mimic the MessageBox layout. And this was my initial question .

    Andre

  4. #4
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,731
    Vote Rating
    90
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default


    I'm not seeing a question in this latest post - are you just clarifying what you are doing?

    Given the amount of workarounds you are already adding, I don't think you would be making the code that much more brittle by copying the useful parts of MessageBox. As said, it is really just that setup code in getDialog() that does the look and feel aspects.

  5. #5
    Sencha User
    Join Date
    Sep 2011
    Location
    Leipzig, Germany
    Posts
    75
    Vote Rating
    1
    A.Rothe is on a distinguished road

      0  

    Default


    You're right. Sometimes it is simpler to copy the whole code instead to parameterize an existing class....

    Btw, the missing questing was: How do I these things simpler...

    André

Thread Participants: 1

Tags for this Thread