mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
AsyncPopupStep to prepare real PopupStep in background
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.popup;
|
||||
|
||||
import com.intellij.openapi.ui.popup.PopupStep;
|
||||
|
||||
public interface NextStepHandler {
|
||||
void handleNextStep(final PopupStep nextStep, Object parentValue);
|
||||
}
|
||||
@@ -25,6 +25,8 @@ import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.ui.PopupBorder;
|
||||
import com.intellij.ui.ScreenUtil;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.popup.async.AsyncPopupImpl;
|
||||
import com.intellij.ui.popup.async.AsyncPopupStep;
|
||||
import com.intellij.ui.popup.list.ListPopupImpl;
|
||||
import com.intellij.ui.popup.tree.TreePopupImpl;
|
||||
import com.intellij.ui.popup.util.MnemonicsSearch;
|
||||
@@ -394,6 +396,9 @@ public abstract class WizardPopup extends AbstractPopup implements ActionListene
|
||||
}
|
||||
|
||||
protected WizardPopup createPopup(WizardPopup parent, PopupStep step, Object parentValue) {
|
||||
if (step instanceof AsyncPopupStep) {
|
||||
return new AsyncPopupImpl(parent, (AsyncPopupStep)step, parentValue);
|
||||
}
|
||||
if (step instanceof ListPopupStep) {
|
||||
return new ListPopupImpl(parent, (ListPopupStep)step, parentValue);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.popup.async;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.ui.popup.PopupStep;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.ui.popup.NextStepHandler;
|
||||
import com.intellij.ui.popup.WizardPopup;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.ui.AsyncProcessIcon;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class AsyncPopupImpl extends WizardPopup implements Runnable {
|
||||
|
||||
private final Future<PopupStep> myFuture;
|
||||
private final Object myParentValue;
|
||||
private final NextStepHandler myCallBackParent;
|
||||
private final Alarm myAlarm;
|
||||
private JPanel myPanel;
|
||||
|
||||
public AsyncPopupImpl(@Nullable WizardPopup parent, @NotNull AsyncPopupStep step, Object parentValue) {
|
||||
super(parent, step);
|
||||
|
||||
if (!(parent instanceof NextStepHandler)) throw new IllegalArgumentException("parent must be NextStepHandler");
|
||||
|
||||
myCallBackParent = (NextStepHandler)parent;
|
||||
myParentValue = parentValue;
|
||||
|
||||
myFuture = ApplicationManager.getApplication().executeOnPooledThread(step);
|
||||
|
||||
myAlarm = new Alarm(this);
|
||||
myAlarm.addRequest(this, 200);
|
||||
Disposer.register(this, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (!myFuture.isCancelled() && !myFuture.isDone()) {
|
||||
myFuture.cancel(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (myFuture.isCancelled()) return;
|
||||
|
||||
if (myFuture.isDone()) {
|
||||
goBack();
|
||||
try {
|
||||
myCallBackParent.handleNextStep(myFuture.get(), myParentValue);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
//ignore
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
//ignore
|
||||
}
|
||||
return;
|
||||
}
|
||||
myAlarm.addRequest(this, 200);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createContent() {
|
||||
if (myPanel != null) return myPanel;
|
||||
myPanel = new JPanel(new BorderLayout());
|
||||
myPanel.add(new AsyncProcessIcon("Async Popup Step"), BorderLayout.WEST);
|
||||
myPanel.add(new JBLabel("Loading..."), BorderLayout.CENTER);
|
||||
myPanel.setBorder(new EmptyBorder(UIUtil.getListCellPadding()));
|
||||
myPanel.setBackground(UIUtil.getListSelectionBackground());
|
||||
myPanel.registerKeyboardAction(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
goBack();
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), JComponent.WHEN_FOCUSED);
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent getPreferredFocusableComponent() {
|
||||
return createContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InputMap getInputMap() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActionMap getActionMap() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onChildSelectedFor(Object value) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ui.popup.async;
|
||||
|
||||
import com.intellij.openapi.ui.popup.MnemonicNavigationFilter;
|
||||
import com.intellij.openapi.ui.popup.PopupStep;
|
||||
import com.intellij.openapi.ui.popup.SpeedSearchFilter;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* Use this "mock" popup step when you need long processing (I/O, network activity etc.) to build real one.
|
||||
* The real example is a list of processes on remote host you can connect to with debugger.
|
||||
* This step would be started as 'callable' on pooled thread as soon as AsyncPopupImpl instance with "Loading..." text is being created
|
||||
* When real popup step is obtained from the background task, mock item would be automatically replaced with it.
|
||||
*/
|
||||
public abstract class AsyncPopupStep implements PopupStep, Callable<PopupStep> {
|
||||
@Nullable
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PopupStep onChosen(Object selectedValue, boolean finalChoice) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSubstep(Object selectedValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void canceled() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMnemonicsNavigationEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public MnemonicNavigationFilter getMnemonicNavigationFilter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpeedSearchEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public SpeedSearchFilter getSpeedSearchFilter() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoSelectionEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Runnable getFinalRunnable() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.ui.popup.ClosableByLeftArrow;
|
||||
import com.intellij.ui.popup.HintUpdateSupply;
|
||||
import com.intellij.ui.popup.NextStepHandler;
|
||||
import com.intellij.ui.popup.WizardPopup;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -47,7 +48,7 @@ import java.awt.event.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class ListPopupImpl extends WizardPopup implements ListPopup {
|
||||
public class ListPopupImpl extends WizardPopup implements ListPopup, NextStepHandler {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.ui.popup.list.ListPopupImpl");
|
||||
|
||||
private MyList myList;
|
||||
@@ -421,7 +422,11 @@ public class ListPopupImpl extends WizardPopup implements ListPopup {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleNextStep(final PopupStep nextStep, Object parentValue, InputEvent e) {
|
||||
public void handleNextStep(final PopupStep nextStep, Object parentValue) {
|
||||
handleNextStep(nextStep, parentValue, null);
|
||||
}
|
||||
|
||||
public boolean handleNextStep(final PopupStep nextStep, Object parentValue, InputEvent e) {
|
||||
if (nextStep != PopupStep.FINAL_CHOICE) {
|
||||
final Point point = myList.indexToLocation(myList.getSelectedIndex());
|
||||
SwingUtilities.convertPointToScreen(point, myList);
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.openapi.ui.popup.PopupStep;
|
||||
import com.intellij.openapi.ui.popup.TreePopup;
|
||||
import com.intellij.openapi.ui.popup.TreePopupStep;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.ui.popup.NextStepHandler;
|
||||
import com.intellij.ui.popup.WizardPopup;
|
||||
import com.intellij.ui.treeStructure.SimpleTree;
|
||||
import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder;
|
||||
@@ -46,7 +47,7 @@ import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class TreePopupImpl extends WizardPopup implements TreePopup {
|
||||
public class TreePopupImpl extends WizardPopup implements TreePopup, NextStepHandler {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.ui.popup.tree.TreePopupImpl");
|
||||
private MyTree myWizardTree;
|
||||
|
||||
@@ -382,7 +383,7 @@ public class TreePopupImpl extends WizardPopup implements TreePopup {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleNextStep(PopupStep nextStep, Object parentValue) {
|
||||
public void handleNextStep(PopupStep nextStep, Object parentValue) {
|
||||
final Rectangle pathBounds = myWizardTree.getPathBounds(myWizardTree.getSelectionPath());
|
||||
final Point point = new RelativePoint(myWizardTree, new Point(getContent().getWidth() + 2, (int) pathBounds.getY())).getScreenPoint();
|
||||
myChild = createPopup(this, nextStep, parentValue);
|
||||
|
||||
Reference in New Issue
Block a user