Skip to content

Commit d1ac397

Browse files
committed
#5987: Use the currently active dialog as the presenter parent.
1 parent ff991ea commit d1ac397

File tree

10 files changed

+227
-119
lines changed

10 files changed

+227
-119
lines changed

platform/core.windows/src/org/netbeans/core/windows/services/DialogDisplayerImpl.java

Lines changed: 37 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import javax.swing.SwingUtilities;
4343
import org.netbeans.core.windows.view.ui.DefaultSeparateContainer;
4444
import org.openide.util.Lookup;
45+
import org.openide.util.Utilities;
4546
import org.openide.util.lookup.ServiceProvider;
4647

4748
/**
@@ -95,53 +96,46 @@ public Dialog createDialog (final DialogDescriptor d, final Frame preferredParen
9596
}
9697
return Mutex.EVENT.readAccess (new Mutex.Action<Dialog> () {
9798
public Dialog run () {
98-
// if a modal dialog active use it as parent
99-
// otherwise use the main window
100-
if (NbPresenter.currentModalDialog != null) {
101-
NbDialog dlg;
102-
if (NbPresenter.currentModalDialog.isLeaf ()) {
103-
dlg = new NbDialog(d, WindowManager.getDefault ().getMainWindow ());
104-
} else {
105-
dlg = new NbDialog(d, NbPresenter.currentModalDialog);
106-
}
107-
customizeDlg(dlg);
108-
return dlg;
109-
}
110-
else {
111-
Window w = preferredParent;
112-
if( null == w ) {
113-
w = KeyboardFocusManager.getCurrentKeyboardFocusManager ().getActiveWindow ();
114-
if (!(w instanceof NbPresenter) || !w.isVisible()) {
115-
// undocked window is not instanceof NbPresenter although it's NetBeans's native window
116-
// all docked windows implements ModeUIBase interface
117-
if (! (w instanceof DefaultSeparateContainer.ModeUIBase)) {
118-
Container cont = SwingUtilities.getAncestorOfClass(Window.class, w);
119-
if (cont instanceof DefaultSeparateContainer.ModeUIBase) {
120-
w = (Window) cont;
121-
} else {
122-
// don't set non-ide window as parent
123-
w = WindowManager.getDefault ().getMainWindow ();
124-
}
99+
Window w = preferredParent;
100+
if( null == w ) {
101+
w = findDialogParent();
102+
if (!(w instanceof NbPresenter) || !w.isVisible()) {
103+
// undocked window is not instanceof NbPresenter although it's NetBeans's native window
104+
// all docked windows implements ModeUIBase interface
105+
if (! (w instanceof DefaultSeparateContainer.ModeUIBase)) {
106+
Container cont = SwingUtilities.getAncestorOfClass(Window.class, w);
107+
if (cont instanceof DefaultSeparateContainer.ModeUIBase) {
108+
w = (Window) cont;
109+
} else {
110+
// don't set non-ide window as parent
111+
w = WindowManager.getDefault ().getMainWindow ();
125112
}
126-
} else if (w instanceof NbPresenter && ((NbPresenter) w).isLeaf ()) {
127-
w = WindowManager.getDefault ().getMainWindow ();
128113
}
129114
}
130-
NbDialog dlg;
131-
if (w instanceof Dialog) {
132-
dlg = new NbDialog(d, (Dialog) w);
133-
} else {
134-
Frame f = w instanceof Frame ? (Frame) w : WindowManager.getDefault ().getMainWindow ();
135-
dlg = new NbDialog(d, f);
136-
}
137-
customizeDlg(dlg);
138-
dlg.requestFocusInWindow ();
139-
return dlg;
140115
}
116+
NbDialog dlg = new NbDialog(d, w);
117+
customizeDlg(dlg);
118+
dlg.requestFocusInWindow ();
119+
return dlg;
141120
}
142121
});
143122
}
144123

124+
private Window findDialogParent() {
125+
Component parentComponent = Utilities.findDialogParent(null, WindowManager.getDefault()::getMainWindow);
126+
if (parentComponent instanceof Window) {
127+
return (Window) parentComponent;
128+
}
129+
Window parent = null;
130+
if (parentComponent != null) {
131+
parent = SwingUtilities.windowForComponent(parentComponent);
132+
}
133+
if (parent == null || parent instanceof NbPresenter && ((NbPresenter) parent).isLeaf ()) {
134+
return WindowManager.getDefault().getMainWindow();
135+
}
136+
return parent;
137+
}
138+
145139
/** Notifies user by a dialog.
146140
* @param descriptor description that contains needed informations
147141
* @return the option that has been choosen in the notification.
@@ -222,43 +216,13 @@ public void showDialog () {
222216
while ((win != null) && (!(win instanceof Window))) win = win.getParent ();
223217
if (win != null) focusOwner = ((Window)win).getFocusOwner ();
224218

225-
// if a modal dialog is active use it as parent
226-
// otherwise use the main window
227-
228219
NbPresenter presenter;
220+
Window parent = noParent ? null : findDialogParent();
221+
229222
if (descriptor instanceof DialogDescriptor) {
230-
if (NbPresenter.currentModalDialog != null) {
231-
if (NbPresenter.currentModalDialog.isLeaf ()) {
232-
presenter = new NbDialog((DialogDescriptor) descriptor, WindowManager.getDefault ().getMainWindow ());
233-
} else {
234-
presenter = new NbDialog((DialogDescriptor) descriptor, NbPresenter.currentModalDialog);
235-
}
236-
} else {
237-
Window w = KeyboardFocusManager.getCurrentKeyboardFocusManager ().getActiveWindow ();
238-
if (w instanceof NbPresenter && ((NbPresenter) w).isLeaf ()) {
239-
w = WindowManager.getDefault ().getMainWindow ();
240-
}
241-
Frame f = w instanceof Frame ? (Frame) w : WindowManager.getDefault().getMainWindow();
242-
if (noParent) {
243-
f = null;
244-
}
245-
presenter = new NbDialog((DialogDescriptor) descriptor, f);
246-
}
223+
presenter = new NbDialog((DialogDescriptor) descriptor, parent);
247224
} else {
248-
if (NbPresenter.currentModalDialog != null) {
249-
if (NbPresenter.currentModalDialog.isLeaf()) {
250-
presenter = new NbPresenter(descriptor, WindowManager.getDefault().getMainWindow(), true);
251-
} else {
252-
presenter = new NbPresenter(descriptor, NbPresenter.currentModalDialog, true);
253-
}
254-
} else {
255-
Window w = KeyboardFocusManager.getCurrentKeyboardFocusManager ().getActiveWindow ();
256-
Frame f = w instanceof Frame ? (Frame) w : WindowManager.getDefault().getMainWindow();
257-
if (noParent) {
258-
f = null;
259-
}
260-
presenter = new NbPresenter(descriptor, f, true);
261-
}
225+
presenter = new NbPresenter(descriptor, parent, Dialog.DEFAULT_MODALITY_TYPE);
262226
}
263227

264228
synchronized (this) {

platform/core.windows/src/org/netbeans/core/windows/services/NbDialog.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,15 @@ public NbDialog (DialogDescriptor d, Dialog owner) {
5050
super (d, owner, d.isModal ());
5151
}
5252

53-
/** Geter for help.
53+
/** Creates a new Dialog from specified DialogDescriptor
54+
* @param d The DialogDescriptor to create the dialog from
55+
* @param owner Owner of this dialog.
56+
*/
57+
public NbDialog(DialogDescriptor d, Window owner) {
58+
super(d, owner, d.isModal() ? Dialog.DEFAULT_MODALITY_TYPE : ModalityType.MODELESS);
59+
}
60+
61+
/** Getter for help.
5462
*/
5563
@Override
5664
protected HelpCtx getHelpCtx () {

platform/core.windows/src/org/netbeans/core/windows/services/NbPresenter.java

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import java.awt.DefaultKeyboardFocusManager;
2727
import java.awt.Dialog;
2828
import java.awt.Dimension;
29-
import java.awt.EventQueue;
3029
import java.awt.FlowLayout;
3130
import java.awt.Frame;
3231
import java.awt.GraphicsDevice;
@@ -89,7 +88,6 @@
8988
import org.openide.NotifyDescriptor;
9089
import org.openide.WizardDescriptor;
9190
import org.openide.awt.Mnemonics;
92-
import org.openide.util.ChangeSupport;
9391
import org.openide.util.HelpCtx;
9492
import org.openide.util.ImageUtilities;
9593
import org.openide.util.Mutex;
@@ -106,9 +104,6 @@
106104
class NbPresenter extends JDialog
107105
implements PropertyChangeListener, WindowListener, Mutex.Action<Void>, Comparator<Object> {
108106

109-
/** variable holding current modal dialog in the system */
110-
public static NbPresenter currentModalDialog;
111-
private static final ChangeSupport cs = new ChangeSupport(NbPresenter.class);
112107
private static Boolean isJava17 = null;
113108

114109
protected NotifyDescriptor descriptor;
@@ -189,6 +184,21 @@ public NbPresenter(NotifyDescriptor d, Dialog owner, boolean modal) {
189184
initialize(d);
190185
}
191186

187+
/**
188+
* Creates a new Dialog from the specified NotifyDescriptor and owner.
189+
*
190+
* @param d the non-null descriptor from which to initialize the dialog
191+
* @param owner the owner of the dialog, must be a {@code Dialog} or
192+
* {@code Frame} instance or {@code null} (not recommended)
193+
* @param modality specifies whether dialog blocks input to other windows
194+
* when shown. {@code null} value and unsupported modality types are
195+
* equivalent to {@code MODELESS}
196+
*/
197+
public NbPresenter(NotifyDescriptor d, Window owner, ModalityType modality) {
198+
super(owner, d.getTitle(), modality);
199+
initialize(d);
200+
}
201+
192202
boolean isLeaf () {
193203
return leaf;
194204
}
@@ -1092,6 +1102,7 @@ public void run () {
10921102
}
10931103
}
10941104

1105+
@Override
10951106
public Void run() {
10961107
doShow();
10971108
return null;
@@ -1108,30 +1119,21 @@ private void doShow () {
11081119
gd.setFullScreenWindow( null );
11091120
}
11101121
}
1111-
NbPresenter prev = null;
11121122
try {
11131123
MenuSelectionManager.defaultManager().clearSelectedPath();
11141124
} catch( NullPointerException npE ) {
11151125
//#216184
11161126
LOG.log( Level.FINE, null, npE );
11171127
}
1118-
if (isModal()) {
1119-
prev = currentModalDialog;
1120-
currentModalDialog = this;
1121-
fireChangeEvent();
1122-
}
11231128

11241129
superShow();
11251130

1126-
if( null != fullScreenWindow )
1131+
if( null != fullScreenWindow ) {
11271132
getGraphicsConfiguration().getDevice().setFullScreenWindow( fullScreenWindow );
1128-
1129-
if (currentModalDialog != prev) {
1130-
currentModalDialog = prev;
1131-
fireChangeEvent();
11321133
}
11331134
}
11341135

1136+
@Override
11351137
public void propertyChange(final java.beans.PropertyChangeEvent evt) {
11361138
if( !SwingUtilities.isEventDispatchThread() ) {
11371139
SwingUtilities.invokeLater(new Runnable() {
@@ -1274,19 +1276,13 @@ public void windowClosing(final java.awt.event.WindowEvent p1) {
12741276
public void windowActivated(final java.awt.event.WindowEvent p1) {
12751277
}
12761278

1277-
// Used by JavaHelp:
1279+
@Deprecated
12781280
public static void addChangeListener(ChangeListener l) {
1279-
cs.addChangeListener(l);
1281+
// Does nothing
12801282
}
1283+
@Deprecated
12811284
public static void removeChangeListener(ChangeListener l) {
1282-
cs.removeChangeListener(l);
1283-
}
1284-
private static void fireChangeEvent() {
1285-
EventQueue.invokeLater(new Runnable() {
1286-
public void run() {
1287-
cs.fireChange();
1288-
}
1289-
});
1285+
// Does nothing
12901286
}
12911287

12921288
private final class EscapeAction extends AbstractAction {

platform/core.windows/src/org/netbeans/core/windows/services/NodeOperationImpl.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.openide.util.Mutex;
5252
import org.openide.util.NbBundle;
5353
import org.openide.util.UserCancelException;
54+
import org.openide.util.Utilities;
5455
import org.openide.util.WeakSet;
5556
import org.openide.util.lookup.ServiceProvider;
5657
import org.openide.windows.Mode;
@@ -350,12 +351,7 @@ private static void openProperties (final NbSheet sheet, final Node[] nds) {
350351
// Mutex.EVENT.readAccess (new Runnable () { // PENDING
351352
javax.swing.SwingUtilities.invokeLater(new Runnable() {
352353
public void run () {
353-
boolean modal;
354-
if(NbPresenter.currentModalDialog == null) {
355-
modal = false;
356-
} else {
357-
modal = true;
358-
}
354+
boolean modal = Utilities.isModalDialogOpen();
359355

360356
Dialog dlg = org.openide.DialogDisplayer.getDefault().createDialog(new DialogDescriptor (
361357
sheet,

platform/core.windows/test/unit/src/org/netbeans/core/windows/services/DialogDisplayerImplTest.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.awt.Dialog;
2424
import java.awt.EventQueue;
2525
import java.awt.Frame;
26+
import java.awt.KeyboardFocusManager;
2627
import java.awt.Window;
2728
import java.util.concurrent.CancellationException;
2829
import java.util.concurrent.CompletableFuture;
@@ -81,10 +82,13 @@ protected void setUp() throws Exception {
8182

8283
@Override
8384
protected void tearDown() throws Exception {
84-
if (NbPresenter.currentModalDialog != null) {
85-
NbPresenter.currentModalDialog.setVisible(false);
86-
NbPresenter.currentModalDialog.dispose();
87-
NbPresenter.currentModalDialog = null;
85+
while (true) {
86+
Window w = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
87+
if (w == null) {
88+
break;
89+
}
90+
w.setVisible(false);
91+
w.dispose();
8892
}
8993
super.tearDown();
9094
}
@@ -347,6 +351,22 @@ public void testParent() {
347351
assertEquals(frame, dlg.getOwner());
348352
}
349353

354+
@RandomlyFails
355+
public void testNestedDialogParent() throws Exception {
356+
Frame f = null;
357+
Dialog owner = new Dialog(f, true);
358+
postInAwtAndWaitOutsideAwt(() -> owner.setVisible(true));
359+
assertShowing("Owner is invisible", true, owner);
360+
361+
child = new JButton();
362+
final NotifyDescriptor nd = new NotifyDescriptor.Message(child);
363+
postInAwtAndWaitOutsideAwt(() -> DialogDisplayer.getDefault().notify(nd));
364+
365+
assertShowing("Child is invisible", true, child);
366+
Window w = SwingUtilities.windowForComponent(child);
367+
assertSame("Window parent is not owner", owner, w.getParent());
368+
}
369+
350370
static void postInAwtAndWaitOutsideAwt (final Runnable run) throws Exception {
351371
// pendig to better implementation
352372
SwingUtilities.invokeLater (run);
@@ -444,7 +464,7 @@ public void testUserCancelClosesDialog() throws Exception {
444464
thenApply((x) -> x);
445465

446466
// wait for the dialog to be displayed
447-
panel.displayed.await(10, TimeUnit.SECONDS);
467+
assertTrue(panel.displayed.await(10, TimeUnit.SECONDS));
448468

449469
cf.cancel(true);
450470

0 commit comments

Comments
 (0)