IDEA-159742 IllegalArgumentException: parent must be showing

This commit is contained in:
Denis Fokin
2016-08-11 19:43:06 +03:00
parent 4e93617043
commit 87f74398b9
4 changed files with 123 additions and 79 deletions
@@ -87,7 +87,7 @@ public class FileChooser {
@Nullable final Project project,
@Nullable final VirtualFile toSelect,
@NotNull final Consumer<List<VirtualFile>> callback) {
chooseFiles(descriptor, project, KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(), toSelect, callback);
chooseFiles(descriptor, project, KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(), toSelect, callback);
}
/**
@@ -54,6 +54,7 @@ import com.intellij.ui.mac.foundation.MacUtil;
import com.intellij.util.IJSwingUtilities;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.ui.JBInsets;
import com.intellij.util.ui.OwnerOptional;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -175,18 +176,16 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
*/
protected DialogWrapperPeerImpl(@NotNull DialogWrapper wrapper, @NotNull Component parent, boolean canBeParent) {
myWrapper = wrapper;
if (!parent.isShowing()) {
throw new IllegalArgumentException("parent must be showing: " + parent);
}
myWindowManager = null;
Application application = ApplicationManager.getApplication();
if (application != null && application.hasComponent(WindowManager.class)) {
myWindowManager = (WindowManagerEx)WindowManager.getInstance();
}
Window owner = parent instanceof Window ? (Window)parent : (Window)SwingUtilities.getAncestorOfClass(Window.class, parent);
if (!(owner instanceof Dialog) && !(owner instanceof Frame)) {
owner = JOptionPane.getRootFrame();
Window owner = OwnerOptional.fromComponent(parent).get();
if (!owner.isShowing()) {
throw new IllegalArgumentException("owner must be showing: " + owner);
}
createDialog(owner, canBeParent);
}
@@ -219,7 +218,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
@Deprecated
public DialogWrapperPeerImpl(@NotNull DialogWrapper wrapper,final Window owner, final boolean canBeParent, final boolean applicationModalIfPossible) {
this(wrapper, owner, canBeParent, applicationModalIfPossible ? DialogWrapper.IdeModalityType.IDE : DialogWrapper.IdeModalityType.PROJECT);
this(wrapper, owner, canBeParent, applicationModalIfPossible ? DialogWrapper.IdeModalityType.IDE : DialogWrapper.IdeModalityType.PROJECT);
}
@Override
@@ -496,7 +495,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra
if (StackingPopupDispatcher.getInstance().isPopupFocused()) return;
JTree tree = UIUtil.getParentOfType(JTree.class, focusOwner);
JTable table = UIUtil.getParentOfType(JTable.class, focusOwner);
if (tree != null || table != null) {
if (hasNoEditingTreesOrTablesUpward(focusOwner)) {
e.getPresentation().setEnabled(true);
@@ -26,18 +26,15 @@ import com.intellij.openapi.fileChooser.FileChooserDescriptor;
import com.intellij.openapi.fileChooser.PathChooserDialog;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.popup.StackingPopupDispatcher;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.ui.UIBundle;
import com.intellij.ui.popup.AbstractPopup;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.OwnerOptional;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -54,23 +51,25 @@ import java.util.stream.Stream;
public class MacPathChooserDialog implements PathChooserDialog {
private final FileDialog myFileDialog;
private FileDialog myFileDialog;
private final FileChooserDescriptor myFileChooserDescriptor;
private final Component myParent;
private final String myTitle;
public MacPathChooserDialog(FileChooserDescriptor descriptor, Component parent, Project project) {
//StackingPopupDispatcher.getInstance().hidePersistentPopups();
//myDisposeActions.add(() -> StackingPopupDispatcher.getInstance().restorePersistentPopups());
myFileDialog = parent != null
? createFileDialogWithOwner(findOwnerByComponent(parent), descriptor.getTitle(), FileDialog.LOAD)
: createFileDialogWithoutOwner(descriptor.getTitle(), FileDialog.LOAD);
myFileChooserDescriptor = descriptor;
myParent = parent;
myTitle = getChooserTitle(descriptor);
Consumer<Dialog> dialogConsumer = owner -> myFileDialog = new FileDialog(owner, myTitle, FileDialog.LOAD);
Consumer<Frame> frameConsumer = owner -> myFileDialog = new FileDialog(owner, myTitle, FileDialog.LOAD);
OwnerOptional
.fromComponent(parent)
.ifDialog(dialogConsumer)
.ifFrame(frameConsumer)
.ifNull(frameConsumer);
}
private static String getChooserTitle(final FileChooserDescriptor descriptor) {
@@ -139,64 +138,6 @@ public class MacPathChooserDialog implements PathChooserDialog {
}
}
@NotNull
private static Window findOwnerByComponent(@NotNull Component component) {
return (component instanceof Window) ? (Window) component : SwingUtilities.getWindowAncestor(component);
}
@NotNull
private static FileDialog createFileDialogWithOwner(@NotNull Window owner, String title, int mode) {
FileDialog fileDialog;
IdePopupManager manager = IdeEventQueue.getInstance().getPopupManager();
if (manager.isPopupWindow(owner)) {
manager.closeAllPopups();
owner = owner.getOwner();
while (owner != null
&& !(owner instanceof Dialog)
&& !(owner instanceof Frame)) {
owner = owner.getOwner();
}
}
if (owner instanceof Dialog) {
Dialog ownerDialog = (Dialog)owner;
if (ownerDialog.isModal()) {
owner = ownerDialog;
}
else {
while (owner instanceof Dialog && !((Dialog)owner).isModal()) {
owner = owner.getOwner();
}
}
}
if (owner == null) {
fileDialog = createFileDialogWithoutOwner(title, mode);
}
else {
if (owner instanceof Frame) {
if (owner instanceof IdeFrame.Child) {
IdeFrame.Child ideFrameChild = (IdeFrame.Child)owner;
owner = WindowManager.getInstance().getFrame(ideFrameChild.getProject());
}
fileDialog = new FileDialog((Frame)owner, title, mode);
}
else if (owner instanceof Dialog) {
fileDialog = new FileDialog((Dialog)owner, title, mode);
}
else {
throw new RuntimeException("Owner should be a frame or a dialog");
}
}
return fileDialog;
}
@NotNull
private static FileDialog createFileDialogWithoutOwner(String title, int load) {
// This is bad. But sometimes we do not have any windows at all.
@@ -0,0 +1,104 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util.ui;
import com.intellij.ide.IdeEventQueue;
import com.intellij.ide.IdePopupManager;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
/**
* @author Denis Fokin
*/
public class OwnerOptional {
@NotNull
private static Window findOwnerByComponent(@NotNull Component component) {
return (component instanceof Window) ? (Window) component : SwingUtilities.getWindowAncestor(component);
}
private Window myPermanentOwner;
private OwnerOptional(Window permanentOwner) {
this.myPermanentOwner = permanentOwner;
}
public static OwnerOptional fromComponent (Component parentComponent) {
Window owner = findOwnerByComponent(parentComponent);
IdePopupManager manager = IdeEventQueue.getInstance().getPopupManager();
if (manager.isPopupWindow(owner)) {
manager.closeAllPopups();
owner = owner.getOwner();
while (owner != null
&& !(owner instanceof Dialog)
&& !(owner instanceof Frame)) {
owner = owner.getOwner();
}
}
if (owner instanceof Dialog) {
Dialog ownerDialog = (Dialog)owner;
if (ownerDialog.isModal()) {
owner = ownerDialog;
}
else {
while (owner instanceof Dialog && !((Dialog)owner).isModal()) {
owner = owner.getOwner();
}
}
}
return new OwnerOptional(owner);
}
public OwnerOptional ifDialog(Consumer<Dialog> consumer) {
if (myPermanentOwner instanceof Dialog) {
consumer.consume((Dialog)myPermanentOwner);
}
return this;
}
public OwnerOptional ifNull(Consumer<Frame> consumer) {
consumer.consume((Frame)this.myPermanentOwner);
return this;
}
public OwnerOptional ifFrame(Consumer<Frame> consumer) {
if (myPermanentOwner instanceof Frame) {
if (myPermanentOwner instanceof IdeFrame.Child) {
IdeFrame.Child ideFrameChild = (IdeFrame.Child)myPermanentOwner;
myPermanentOwner = WindowManager.getInstance().getFrame(ideFrameChild.getProject());
}
consumer.consume((Frame)this.myPermanentOwner);
}
return this;
}
public Window get() {
return myPermanentOwner;
}
}