private void buildGUI() {
    // add all page components to grid layout panel
    pagesPanel = new JPanel();
    pagesPanel.setBackground(backgroundColor);
    // one column equals single page view continuous
    GridLayout gridLayout = new GridLayout(0, 1, horizontalSpace, verticalSpace);
    pagesPanel.setLayout(gridLayout);

    // use a grid bag to center the page component panel
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.weighty = 1.0; // allows vertical resizing
    gbc.weightx = 1.0; // allows horizontal resizing
    gbc.insets = // component spacer [top, left, bottom, right]
        new Insets(layoutInserts, layoutInserts, layoutInserts, layoutInserts);
    gbc.gridwidth = GridBagConstraints.REMAINDER; // one component per row

    this.setLayout(new GridBagLayout());
    this.add(pagesPanel, gbc);

    // finally add all the components
    // add components for every page in the document
    List<AbstractPageViewComponent> pageComponents = documentViewModel.getPageComponents();

    if (pageComponents != null) {
      for (PageViewComponent pageViewComponent : pageComponents) {
        if (pageViewComponent != null) {
          pageViewComponent.setDocumentViewCallback(this);
          // add component to layout
          pagesPanel.add(new PageViewDecorator((AbstractPageViewComponent) pageViewComponent));
        }
      }
    }
  }
  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);
    }
  }