AWT/Swing allows to show application modal (blocking the whole application) and parent modal (blocking only the parents) dialogs. How can I achieve the same with SWT?
In order to block the whole application, you can create the dialog Shell
with the style SWT.APPLICATION_MODAL
, open it, and then pump the UI events until the shell is disposed:
Display display = Display.getDefault();
Shell dialogShell = new Shell(display, SWT.APPLICATION_MODAL);
// populate dialogShell
dialogShell.open();
while (!dialogShell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
If you want to block input only to the parent, try using the style SWT.PRIMARY_MODAL
, though the Javadocs specify (as for the other modal styles) that this is a hint; i.e., that different SWT implementations may not exactly handle it the same way. Likewise, I don't know of an implementation that would honor the SWT.SYSTEM_MODAL
style.
UPDATE: Answer to first comment
If you have two or more primary modals open at the same time, you cannot use the tricks to pump the events until the modal is closed, as they could be closed in any order. The code will run, but execution will resume after the while loop after the current dialog is closed and all other such dialogs that have been opened after it. In this case, I would register a DisposeListener
on each dialog to get a callback when they are closed. Something like this:
void run() {
Display display = new Display();
Shell shell1 = openDocumentShell(display);
Shell shell2 = openDocumentShell(display);
// close both shells to exit
while (!shell1.isDisposed() || !shell2.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
Shell openDocumentShell(final Display display) {
final Shell shell = new Shell(display, SWT.SHELL_TRIM);
shell.setLayout(new FillLayout());
Button button = new Button(shell, SWT.PUSH);
button.setText("Open Modal Dialog");
button.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
System.out.println("Button pressed, about to open modal dialog");
final Shell dialogShell = new Shell(shell, SWT.PRIMARY_MODAL | SWT.SHEET);
dialogShell.setLayout(new FillLayout());
Button closeButton = new Button(dialogShell, SWT.PUSH);
closeButton.setText("Close");
closeButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
dialogShell.dispose();
}
});
dialogShell.setDefaultButton(closeButton);
dialogShell.addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
System.out.println("Modal dialog closed");
}
});
dialogShell.pack();
dialogShell.open();
}
});
shell.pack();
shell.open();
return shell;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With