private void setHeaderComponent(JComponent c) { boolean doRevalidate = false; if (myHeaderComponent != null) { myHeaderPanel.remove(myHeaderComponent); myHeaderPanel.add(myCaption, BorderLayout.NORTH); myHeaderComponent = null; doRevalidate = true; } if (c != null) { myHeaderPanel.remove(myCaption); myHeaderPanel.add(c, BorderLayout.NORTH); myHeaderComponent = c; final Dimension size = myContent.getSize(); if (size.height < c.getPreferredSize().height * 2) { size.height += c.getPreferredSize().height; setSize(size); } doRevalidate = true; } if (doRevalidate) myContent.revalidate(); }
private void setWindowActive(boolean active) { boolean value = myHeaderAlwaysFocusable || active; if (myCaption != null) { myCaption.setActive(value); } myPopupBorder.setActive(value); myContent.repaint(); }
@Override public Point getLocationOnScreen() { Dimension headerCorrectionSize = myLocateByContent ? myHeaderPanel.getPreferredSize() : null; Point screenPoint = myContent.getLocationOnScreen(); if (headerCorrectionSize != null) { screenPoint.y -= headerCorrectionSize.height; } return screenPoint; }
public void cancel(InputEvent e) { if (isDisposed()) return; if (myPopup != null) { if (!canClose()) { return; } storeDimensionSize(myContent.getSize()); if (myUseDimServiceForXYLocation) { final JRootPane root = myComponent.getRootPane(); if (root != null) { final Container popupWindow = root.getParent(); if (popupWindow != null && popupWindow.isShowing()) { storeLocation(popupWindow.getLocationOnScreen()); } } } if (e instanceof MouseEvent) { IdeEventQueue.getInstance().blockNextEvents(((MouseEvent) e)); } myPopup.hide(false); if (ApplicationManagerEx.getApplicationEx() != null) { StackingPopupDispatcher.getInstance().onPopupHidden(this); } if (myInStack) { myFocusTrackback.setForcedRestore(!myOk && myFocusable); myFocusTrackback.restoreFocus(); } disposePopup(); if (myListeners != null) { for (JBPopupListener each : myListeners) { each.onClosed(new LightweightWindowEvent(this, myOk)); } } } Disposer.dispose(this, false); }
@Override public void pack(boolean width, boolean height) { if (!isVisible() || (!width && !height)) return; Dimension size = getSize(); Dimension prefSize = myContent.computePreferredSize(); if (width) { size.width = prefSize.width; } if (height) { size.height = prefSize.height; } size = computeWindowSize(size); final Window window = SwingUtilities.getWindowAncestor(myContent); window.setSize(size); }
public void setAdText(@NotNull final String s, int alignment) { if (myAdComponent == null) { myAdComponent = HintUtil.createAdComponent(s, BorderFactory.createEmptyBorder(1, 5, 1, 5), alignment); JPanel wrapper = new JPanel(new BorderLayout()) { @Override protected void paintComponent(Graphics g) { g.setColor(Gray._135); g.drawLine(0, 0, getWidth(), 0); super.paintComponent(g); } }; wrapper.setOpaque(false); wrapper.setBorder(new EmptyBorder(1, 0, 0, 0)); wrapper.add(myAdComponent, BorderLayout.CENTER); myContent.add(wrapper, BorderLayout.SOUTH); pack(false, true); } else { myAdComponent.setText(s); myAdComponent.setHorizontalAlignment(alignment); } }
private void prepareToShow() { final MouseAdapter mouseAdapter = new MouseAdapter() { public void mousePressed(MouseEvent e) { Point point = (Point) e.getPoint().clone(); SwingUtilities.convertPointToScreen(point, e.getComponent()); final Dimension dimension = myContent.getSize(); dimension.height += myResizable && isToDrawMacCorner() ? ourMacCorner.getHeight(myContent) : 4; dimension.width += 4; Point locationOnScreen = myContent.getLocationOnScreen(); final Rectangle bounds = new Rectangle(new Point(locationOnScreen.x - 2, locationOnScreen.y - 2), dimension); if (!bounds.contains(point)) { cancel(); } } }; myContent.addMouseListener(mouseAdapter); Disposer.register( this, new Disposable() { public void dispose() { myContent.removeMouseListener(mouseAdapter); } }); myContent.registerKeyboardAction( new ActionListener() { public void actionPerformed(ActionEvent e) { if (myCancelKeyEnabled) { cancel(); } } }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); mySearchKeyListener = new SpeedSearchKeyListener(); myContent.addKeyListener(mySearchKeyListener); if (myCancelOnMouseOutCallback != null || myCancelOnWindow) { myMouseOutCanceller = new Canceller(); Toolkit.getDefaultToolkit() .addAWTEventListener( myMouseOutCanceller, AWTEvent.MOUSE_EVENT_MASK | WindowEvent.WINDOW_ACTIVATED | AWTEvent.MOUSE_MOTION_EVENT_MASK); } myFocusWatcher = new ChildFocusWatcher(myContent) { protected void onFocusGained(final FocusEvent event) { setWindowActive(true); } protected void onFocusLost(final FocusEvent event) { setWindowActive(false); } }; mySpeedSearchPatternField = new JTextField(); if (SystemInfo.isMac) { Font f = mySpeedSearchPatternField.getFont(); mySpeedSearchPatternField.setFont(f.deriveFont(f.getStyle(), f.getSize() - 2)); } }
public void show(Component owner, int aScreenX, int aScreenY, final boolean considerForcedXY) { if (ApplicationManagerEx.getApplicationEx() != null && ApplicationManager.getApplication().isHeadlessEnvironment()) return; if (isDisposed()) { throw new IllegalStateException( "Popup was already disposed. Recreate a new instance to show again"); } assert ApplicationManager.getApplication().isDispatchThread(); addActivity(); final boolean shouldShow = beforeShow(); if (!shouldShow) { removeActivity(); return; } prepareToShow(); if (myInStack) { myFocusTrackback = new FocusTrackback(this, owner, true); myFocusTrackback.setMustBeShown(true); } Dimension sizeToSet = null; if (myDimensionServiceKey != null) { sizeToSet = DimensionService.getInstance().getSize(myDimensionServiceKey, myProject); } if (myForcedSize != null) { sizeToSet = myForcedSize; } if (myMinSize == null) { myMinSize = myContent.getMinimumSize(); } if (sizeToSet == null) { sizeToSet = myContent.getPreferredSize(); } if (sizeToSet != null) { sizeToSet.width = Math.max(sizeToSet.width, myMinSize.width); sizeToSet.height = Math.max(sizeToSet.height, myMinSize.height); myContent.setSize(sizeToSet); myContent.setPreferredSize(sizeToSet); } Point xy = new Point(aScreenX, aScreenY); boolean adjustXY = true; if (myDimensionServiceKey != null) { final Point storedLocation = DimensionService.getInstance().getLocation(myDimensionServiceKey, myProject); if (storedLocation != null) { xy = storedLocation; adjustXY = false; } } if (adjustXY) { final Insets insets = myContent.getInsets(); if (insets != null) { xy.x -= insets.left; xy.y -= insets.top; } } if (considerForcedXY && myForcedLocation != null) { xy = myForcedLocation; } if (myLocateByContent) { final Dimension captionSize = myHeaderPanel.getPreferredSize(); xy.y -= captionSize.height; } Rectangle targetBounds = new Rectangle(xy, myContent.getPreferredSize()); Insets insets = myPopupBorder.getBorderInsets(myContent); if (insets != null) { targetBounds.x += insets.left; targetBounds.y += insets.top; } Rectangle original = new Rectangle(targetBounds); if (myLocateWithinScreen) { ScreenUtil.moveRectangleToFitTheScreen(targetBounds); } if (myMouseOutCanceller != null) { myMouseOutCanceller.myEverEntered = targetBounds.equals(original); } myOwner = IdeFrameImpl.findNearestModalComponent(owner); if (myOwner == null) { myOwner = owner; } myRequestorComponent = owner; boolean forcedDialog = (SystemInfo.isMac && !(myOwner instanceof IdeFrame)) || myMayBeParent; PopupComponent.Factory factory = getFactory(myForcedHeavyweight || myResizable, forcedDialog); myNativePopup = factory.isNativePopup(); myPopup = factory.getPopup(myOwner, myContent, targetBounds.x, targetBounds.y); if (myResizable) { final JRootPane root = myContent.getRootPane(); final IdeGlassPaneImpl glass = new IdeGlassPaneImpl(root); root.setGlassPane(glass); final ResizeComponentListener resizeListener = new ResizeComponentListener(this, glass); glass.addMousePreprocessor(resizeListener, this); glass.addMouseMotionPreprocessor(resizeListener, this); } if (myCaption != null && myMovable) { final MoveComponentListener moveListener = new MoveComponentListener(myCaption) { public void mousePressed(final MouseEvent e) { super.mousePressed(e); if (e.isConsumed()) return; if (UIUtil.isCloseClick(e)) { if (myCaption.isWithinPanel(e)) { cancel(); } } } }; ListenerUtil.addMouseListener(myCaption, moveListener); ListenerUtil.addMouseMotionListener(myCaption, moveListener); final MyContentPanel saved = myContent; Disposer.register( this, new Disposable() { public void dispose() { ListenerUtil.removeMouseListener(saved, moveListener); ListenerUtil.removeMouseMotionListener(saved, moveListener); } }); } for (JBPopupListener listener : myListeners) { listener.beforeShown(new LightweightWindowEvent(this)); } myPopup.setRequestFocus(myRequestFocus); myPopup.show(); final Window window = SwingUtilities.getWindowAncestor(myContent); myWindowListener = new MyWindowListener(); window.addWindowListener(myWindowListener); if (myFocusable) { window.setFocusableWindowState(true); window.setFocusable(true); } myWindow = updateMaskAndAlpha(window); if (myWindow instanceof JWindow) { ((JWindow) myWindow).getRootPane().putClientProperty(KEY, this); } if (myWindow != null) { // dialogwrapper-based popups do this internally through peer, // for other popups like jdialog-based we should exclude them manually, but // we still have to be able to use IdeFrame as parent if (!myMayBeParent && !(myWindow instanceof Frame)) { WindowManager.getInstance().doNotSuggestAsParent(myWindow); } } final Runnable afterShow = new Runnable() { public void run() { if (myPreferredFocusedComponent != null && myInStack && myFocusable) { myFocusTrackback.registerFocusComponent(myPreferredFocusedComponent); } removeActivity(); afterShow(); } }; if (myRequestFocus) { getFocusManager() .requestFocus( new FocusCommand() { @Override public ActionCallback run() { if (isDisposed()) { removeActivity(); return new ActionCallback.Done(); } _requestFocus(); final ActionCallback result = new ActionCallback(); final Runnable afterShowRunnable = new Runnable() { @Override public void run() { afterShow.run(); result.setDone(); } }; if (myNativePopup) { final FocusRequestor furtherRequestor = getFocusManager().getFurtherRequestor(); SwingUtilities.invokeLater( new Runnable() { @Override public void run() { if (isDisposed()) { result.setRejected(); return; } furtherRequestor .requestFocus( new FocusCommand() { @Override public ActionCallback run() { if (isDisposed()) { return new ActionCallback.Rejected(); } _requestFocus(); afterShowRunnable.run(); return new ActionCallback.Done(); } }, true) .notify(result) .doWhenProcessed( new Runnable() { @Override public void run() { removeActivity(); } }); } }); } else { afterShowRunnable.run(); } return result; } }, true) .doWhenRejected( new Runnable() { @Override public void run() { afterShow.run(); } }); } else { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { if (isDisposed()) { removeActivity(); return; } afterShow.run(); } }); } }
@Override public void setDataProvider(@NotNull DataProvider dataProvider) { if (myContent != null) { myContent.setDataProvider(dataProvider); } }
AbstractPopup init( final Project project, @NotNull final JComponent component, @Nullable final JComponent preferredFocusedComponent, final boolean requestFocus, final boolean focusable, final boolean forceHeavyweight, final boolean movable, final String dimensionServiceKey, final boolean resizable, @Nullable final String caption, @Nullable final Computable<Boolean> callback, final boolean cancelOnClickOutside, @Nullable final Set<JBPopupListener> listeners, final boolean useDimServiceForXYLocation, InplaceButton commandButton, @Nullable final IconButton cancelButton, @Nullable final MouseChecker cancelOnMouseOutCallback, final boolean cancelOnWindow, @Nullable final ActiveIcon titleIcon, final boolean cancelKeyEnabled, final boolean locateBycontent, final boolean placeWithinScreenBounds, @Nullable final Dimension minSize, float alpha, @Nullable MaskProvider maskProvider, boolean inStack, boolean modalContext, @Nullable Component[] focusOwners, @Nullable String adText, int adTextAlignment, final boolean headerAlwaysFocusable, @NotNull List<Pair<ActionListener, KeyStroke>> keyboardActions, Component settingsButtons, @Nullable final Processor<JBPopup> pinCallback, boolean mayBeParent, boolean showShadow) { if (requestFocus && !focusable) { assert false : "Incorrect argument combination: requestFocus=" + requestFocus + " focusable=" + focusable; } myActivityKey = new UiActivity.Focus("Popup:" + this); myProject = project; myComponent = component; myPopupBorder = PopupBorder.Factory.create(true, showShadow); myShadowed = showShadow; myPaintShadow = showShadow && !SystemInfo.isMac && !movable && !resizable && Registry.is("ide.popup.dropShadow"); myContent = createContentPanel(resizable, myPopupBorder, isToDrawMacCorner() && resizable); myMayBeParent = mayBeParent; myContent.add(component, BorderLayout.CENTER); if (adText != null) { setAdText(adText, adTextAlignment); } myCancelKeyEnabled = cancelKeyEnabled; myLocateByContent = locateBycontent; myLocateWithinScreen = placeWithinScreenBounds; myAlpha = alpha; myMaskProvider = maskProvider; myInStack = inStack; myModalContext = modalContext; myFocusOwners = focusOwners; myHeaderAlwaysFocusable = headerAlwaysFocusable; myMovable = movable; ActiveIcon actualIcon = titleIcon == null ? new ActiveIcon(EmptyIcon.ICON_0) : titleIcon; myHeaderPanel = new JPanel(new BorderLayout()); if (caption != null) { if (caption.length() > 0) { myCaption = new TitlePanel(actualIcon.getRegular(), actualIcon.getInactive()); ((TitlePanel) myCaption).setText(caption); } else { myCaption = new CaptionPanel(); } if (pinCallback != null) { myCaption.setButtonComponent( new InplaceButton( new IconButton( "Pin", IconLoader.getIcon("/general/autohideOff.png"), IconLoader.getIcon("/general/autohideOff.png"), IconLoader.getIcon("/general/autohideOffInactive.png")), new ActionListener() { public void actionPerformed(final ActionEvent e) { pinCallback.process(AbstractPopup.this); } })); } else if (cancelButton != null) { myCaption.setButtonComponent( new InplaceButton( cancelButton, new ActionListener() { public void actionPerformed(final ActionEvent e) { cancel(); } })); } else if (commandButton != null) { myCaption.setButtonComponent(commandButton); } } else { myCaption = new CaptionPanel(); myCaption.setBorder(null); myCaption.setPreferredSize(new Dimension(0, 0)); } setWindowActive(myHeaderAlwaysFocusable); myHeaderPanel.add(myCaption, BorderLayout.NORTH); myContent.add(myHeaderPanel, BorderLayout.NORTH); myForcedHeavyweight = true; myResizable = resizable; myPreferredFocusedComponent = preferredFocusedComponent; myRequestFocus = requestFocus; myFocusable = focusable; myDimensionServiceKey = dimensionServiceKey; myCallBack = callback; myCancelOnClickOutside = cancelOnClickOutside; myCancelOnMouseOutCallback = cancelOnMouseOutCallback; myListeners = listeners == null ? new HashSet<JBPopupListener>() : listeners; myUseDimServiceForXYLocation = useDimServiceForXYLocation; myCancelOnWindow = cancelOnWindow; myMinSize = minSize; for (Pair<ActionListener, KeyStroke> pair : keyboardActions) { myContent.registerKeyboardAction( pair.getFirst(), pair.getSecond(), JComponent.WHEN_IN_FOCUSED_WINDOW); } if (settingsButtons != null) { myCaption.addSettingsComponent(settingsButtons); } return this; }
public void dispose() { if (myDisposed) { return; } myDisposed = true; Disposer.dispose(this, false); assert ApplicationManager.getApplication().isDispatchThread(); if (myPopup != null) { cancel(myDisposeEvent); } if (myContent != null) { myContent.removeAll(); myContent.removeKeyListener(mySearchKeyListener); } myContent = null; myPreferredFocusedComponent = null; myComponent = null; myFocusTrackback = null; myCallBack = null; myListeners = null; if (myMouseOutCanceller != null) { final Toolkit toolkit = Toolkit.getDefaultToolkit(); // it may happen, but have no idea how // http://www.jetbrains.net/jira/browse/IDEADEV-21265 if (toolkit != null) { toolkit.removeAWTEventListener(myMouseOutCanceller); } } myMouseOutCanceller = null; if (myFocusWatcher != null) { myFocusWatcher.dispose(); myFocusWatcher = null; } resetWindow(); if (myFinalRunnable != null) { final ActionCallback typeaheadDone = new ActionCallback(); Runnable runFinal = new Runnable() { @Override public void run() { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { typeaheadDone.setDone(); } }); myFinalRunnable.run(); myFinalRunnable = null; } }; IdeFocusManager.getInstance(myProject).typeAheadUntil(typeaheadDone); getFocusManager().doWhenFocusSettlesDown(runFinal); } }