public void calculateCurrentPage() { if (pageComponents != null) { Rectangle viewport = scrollpane.getViewport().getViewRect(); // find visible pages ArrayList<PageViewComponent> visiblePages = new ArrayList<PageViewComponent>(10); Rectangle pageBounds; int pageCount = 0; for (AbstractPageViewComponent pageComponent : pageComponents) { if (pageComponent != null) { pageBounds = documentViewModel.getPageBounds(pageCount); if (pageBounds != null && pageComponent.isShowing()) { visiblePages.add(pageComponent); } } pageCount++; } // find center point of view port int x = viewport.x + (viewport.width / 2); int y = viewport.y + (viewport.height / 2); Point centerView = new Point(x, y); // find out which page center is closest to center and thus the new current page double minLength = Double.MAX_VALUE; int minPage = -1; double tmpDistance; for (PageViewComponent pageComponent : visiblePages) { if (pageComponent != null) { pageBounds = documentViewModel.getPageBounds(pageComponent.getPageIndex()); x = pageBounds.x + (pageBounds.width / 2); y = pageBounds.y + (pageBounds.height / 2); // find minimum page. tmpDistance = centerView.distance(x, y); if (tmpDistance < minLength) { minLength = tmpDistance; minPage = pageComponent.getPageIndex(); } } } // clean up visiblePages.clear(); visiblePages.trimToSize(); // finally send out event to update page number int oldCurrentPage = documentViewModel.getViewCurrentPageIndex(); documentViewModel.setViewCurrentPageIndex(minPage); DocumentViewControllerImpl documentViewController = (DocumentViewControllerImpl) documentView.getParentViewController(); documentViewController.firePropertyChange( PropertyConstants.DOCUMENT_CURRENT_PAGE, oldCurrentPage, minPage); } }
@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); }