@Override public void moveToFitScreen() { if (myPopup == null) return; final Window popupWindow = SwingUtilities.windowForComponent(myContent); Rectangle bounds = popupWindow.getBounds(); ScreenUtil.moveRectangleToFitTheScreen(bounds); setLocation(bounds.getLocation()); setSize(bounds.getSize(), false); }
public static Point getLocationForCaret(JTextComponent pathTextField) { Point point; int position = pathTextField.getCaretPosition(); try { final Rectangle rec = pathTextField.modelToView(position); point = new Point((int) rec.getMaxX(), (int) rec.getMaxY()); } catch (BadLocationException e) { point = pathTextField.getCaret().getMagicCaretPosition(); } SwingUtilities.convertPointToScreen(point, pathTextField); point.y += 2; return point; }
@Nullable private static Point getVisibleBestPopupLocation(@NotNull Editor editor) { VisualPosition visualPosition = editor.getUserData(ANCHOR_POPUP_POSITION); if (visualPosition == null) { CaretModel caretModel = editor.getCaretModel(); if (caretModel.isUpToDate()) { visualPosition = caretModel.getVisualPosition(); } else { visualPosition = editor.offsetToVisualPosition(caretModel.getOffset()); } } Point p = editor.visualPositionToXY( new VisualPosition(visualPosition.line + 1, visualPosition.column)); final Rectangle visibleArea = editor.getScrollingModel().getVisibleArea(); return visibleArea.contains(p) ? p : null; }
@Override public void show( final Component owner, final int aScreenX, final int aScreenY, final boolean considerForcedXY) { LOG.assertTrue(!isDisposed()); Rectangle targetBounds = new Rectangle(new Point(aScreenX, aScreenY), getContent().getPreferredSize()); ScreenUtil.moveRectangleToFitTheScreen(targetBounds); if (getParent() != null) { final Rectangle parentBounds = getParent().getBounds(); parentBounds.x += STEP_X_PADDING; parentBounds.width -= STEP_X_PADDING * 2; if (parentBounds.intersects(targetBounds)) { targetBounds.x = getParent().getBounds().x - targetBounds.width - STEP_X_PADDING; } } if (getParent() == null) { PopupDispatcher.setActiveRoot(this); } else { PopupDispatcher.setShowing(this); } LOG.assertTrue(!isDisposed(), "Disposed popup, parent=" + getParent()); super.show(owner, targetBounds.x, targetBounds.y, true); }
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(); } }); } }
@NotNull @Override public RelativePoint guessBestPopupLocation(@NotNull final JComponent component) { Point popupMenuPoint = null; final Rectangle visibleRect = component.getVisibleRect(); if (component instanceof JList) { // JList JList list = (JList) component; int firstVisibleIndex = list.getFirstVisibleIndex(); int lastVisibleIndex = list.getLastVisibleIndex(); int[] selectedIndices = list.getSelectedIndices(); for (int index : selectedIndices) { if (firstVisibleIndex <= index && index <= lastVisibleIndex) { Rectangle cellBounds = list.getCellBounds(index, index); popupMenuPoint = new Point(visibleRect.x + visibleRect.width / 4, cellBounds.y + cellBounds.height); break; } } } else if (component instanceof JTree) { // JTree JTree tree = (JTree) component; int[] selectionRows = tree.getSelectionRows(); if (selectionRows != null) { Arrays.sort(selectionRows); for (int i = 0; i < selectionRows.length; i++) { int row = selectionRows[i]; Rectangle rowBounds = tree.getRowBounds(row); if (visibleRect.contains(rowBounds)) { popupMenuPoint = new Point(rowBounds.x + 2, rowBounds.y + rowBounds.height - 1); break; } } if (popupMenuPoint == null) { // All selected rows are out of visible rect Point visibleCenter = new Point( visibleRect.x + visibleRect.width / 2, visibleRect.y + visibleRect.height / 2); double minDistance = Double.POSITIVE_INFINITY; int bestRow = -1; Point rowCenter; double distance; for (int i = 0; i < selectionRows.length; i++) { int row = selectionRows[i]; Rectangle rowBounds = tree.getRowBounds(row); rowCenter = new Point(rowBounds.x + rowBounds.width / 2, rowBounds.y + rowBounds.height / 2); distance = visibleCenter.distance(rowCenter); if (minDistance > distance) { minDistance = distance; bestRow = row; } } if (bestRow != -1) { Rectangle rowBounds = tree.getRowBounds(bestRow); tree.scrollRectToVisible( new Rectangle( rowBounds.x, rowBounds.y, Math.min(visibleRect.width, rowBounds.width), rowBounds.height)); popupMenuPoint = new Point(rowBounds.x + 2, rowBounds.y + rowBounds.height - 1); } } } } else if (component instanceof JTable) { JTable table = (JTable) component; int column = table.getColumnModel().getSelectionModel().getLeadSelectionIndex(); int row = Math.max( table.getSelectionModel().getLeadSelectionIndex(), table.getSelectionModel().getAnchorSelectionIndex()); Rectangle rect = table.getCellRect(row, column, false); if (!visibleRect.intersects(rect)) { table.scrollRectToVisible(rect); } popupMenuPoint = new Point(rect.x, rect.y + rect.height); } else if (component instanceof PopupOwner) { popupMenuPoint = ((PopupOwner) component).getBestPopupPosition(); } if (popupMenuPoint == null) { popupMenuPoint = new Point(visibleRect.x + visibleRect.width / 2, visibleRect.y + visibleRect.height / 2); } return new RelativePoint(component, popupMenuPoint); }