示例#1
0
  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);
  }