Skip to content

Commit

Permalink
IDEA-159742 IllegalArgumentException: parent must be showing
Browse files Browse the repository at this point in the history
  • Loading branch information
Denis Fokin authored and Denis Fokin committed Aug 11, 2016
1 parent 4e93617 commit 87f7439
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public static void chooseFiles(@NotNull final FileChooserDescriptor descriptor,
@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);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
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;
Expand Down Expand Up @@ -175,18 +176,16 @@ public static boolean isHeadlessEnv() {
*/
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);
}
Expand Down Expand Up @@ -219,7 +218,7 @@ public DialogWrapperPeerImpl(@NotNull DialogWrapper wrapper, final boolean canBe

@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
Expand Down Expand Up @@ -496,7 +495,7 @@ public void update(AnActionEvent e) {
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,15 @@
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;

Expand All @@ -54,23 +51,25 @@

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) {
Expand Down Expand Up @@ -139,64 +138,6 @@ else if (callback instanceof FileChooser.FileChooserConsumer) {
}
}

@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.
Expand Down
104 changes: 104 additions & 0 deletions platform/platform-impl/src/com/intellij/util/ui/OwnerOptional.java
Original file line number Diff line number Diff line change
@@ -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;
}
}

0 comments on commit 87f7439

Please sign in to comment.