Modal dialogs

Hi.

Is it possible to use modal dialog like in swing? There when you show modal dialog, it blocks current thread until dialog is closed. Than you can use result from dialog.

something like this

JDialog dialog=new…
dialog.setModal(true)
dialog.show();
if (dialog.status==ok)
{
… something
}

Currently, I am using Vaadin dialogs with callback method, when dialog is closed.

Any ideas?

Sure.


package com.example.wintest;

import com.vaadin.Application;
import com.vaadin.ui.Button;
import com.vaadin.ui.Window;
import com.vaadin.ui.Button.ClickEvent;

public class WintestApplication extends Application {
    @Override
    public void init() {
        final Window mainWindow = new Window("Wintest Application");

        final Window dialog = new Window("Modal dialog");
        dialog.setModal(true);
        mainWindow.addWindow(dialog);
        dialog.addComponent(new Button("Done", new Button.ClickListener() {

            public void buttonClick(ClickEvent event) {
                mainWindow.removeWindow(dialog);

            }
        }));
        setMainWindow(mainWindow);
    }

}

hm…

i ments something like this

void test()
{
final Window dialog = new Window(“Modal dialog”);
dialog.setModal(true);
mainWindow.addWindow(dialog);
int x=dialog.getEnteredNumber();
System.out.println(“x=”+x);
}

Now, the output would always be:

x=0

even if user enters some number in dialog.

Thats because thread doesn’t pause for dialog to close.

That’s true. This is a feature :slight_smile: You probably seen something similar with Swing also.

As Vaadin is an event driven framework you would have to fix your handling code into the listener of textfield value change or some button listener. This is why your method of pulling with (getEnteredNumber()) does not work.

Try using the sample below and move the logic into the buttonClick method.

As Sami explained, this is not possible to do synchronously, but needs to be done asynchronously. Here is an example on how to do it and how to isolate the dialog to a separate generic component.


package com.example.example;

import com.vaadin.Application;
import com.vaadin.ui.Button;
import com.vaadin.ui.Window;
import com.vaadin.ui.Button.ClickEvent;

@SuppressWarnings("serial")
public class ExampleApplication extends Application {

    @Override
    public void init() {
        Window mainWindow = new Window("Example Application");
        mainWindow.addComponent(new Button("Test", new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                test();
            }
        }));
        setMainWindow(mainWindow);
    }

    void test() {
        new InputDialog(getMainWindow(), "What is your name",
                new InputDialog.Recipient() {
                    public void gotInput(String input) {
                        System.out.println("His name is " + input);
                    }
                });
    }
}

package com.example.example;

import com.vaadin.ui.Button;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Window;
import com.vaadin.ui.Button.ClickEvent;

@SuppressWarnings("serial")
public class InputDialog extends Window {
    Recipient r;
    TextField tf = new TextField();

    public InputDialog(final Window parent, String question, Recipient recipient) {
        r = recipient;
        setCaption(question);
        setModal(true);
        getLayout().setSizeUndefined();
        addComponent(tf);
        final Window dialog = this;
        addComponent(new Button("Ok", new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                r.gotInput(tf.toString());
                parent.removeWindow(dialog);
            }
        }));
        parent.addWindow(this);
    }

    public interface Recipient {
        public void gotInput(String input);
    }
}

There are many strategies in Swing to mimic thread blocking but … they all take care the the UI thread is not blocked (else when you resize your window, for example, it looks like unresponsive). And this has side effects in the programming style (as not being permitted to touch Swing object from your non UI thread).

The web has, as principle, to not block the request thread (as we don’t block the Swing UI thread), and it would be a very bad idea to try to do it. I understand that your requirement is very simple (blocking modal window), but it’s not possible. And if a web framework proposed that to me, I’d be very skeptical about it’s philosophy and design. I’m afraid that you have to accept to “release” the thread when showing anything to the user (else, the browser will get nothing to display from the server), and expect any answer from the user in an event/listener.

If you come from Swing, you’ll see many paradigm shifts in web programming. Hopefully, you’ll see them much less with Vaadin, than with more classic web frameworks (.Net, Ruby, Servlet/JSP/Struts, Spring MVC,…).

Hope this helps.
John.

Hi.

I came from Swing and dotnet, and I am glad to report that vaadin is not so different. This is a good thing :slight_smile:

the only big difference are modal dialogs and static variables.

br,ivan

In fact Swing has blocking dialogs. The show() method in fact blocks until the user clicks a button and the dialog obtains a result. This is done by show() running its own nested event dispatcher loop as described here:
https://stackoverflow.com/questions/3028842/how-can-swing-dialogs-even-work

Unfortunately this is not possible with Vaadin. However, there is a clever technique called Coroutines which allows you to use Vaadin dialogs as if they were blocking:
http://mavi.logdown.com/posts/3488105-vaadin-kotlin-coroutines