2012-04-11 26 views
0

我有一個簡單的應用程序,允許用戶通過將預定義小部件拖放到單獨的圖層來標記PDF文檔。重寫JScrollPane行爲

我正在使用JScollPane。視口大小相當於一個8.5x11頁面。當VScrollBar位於最小位置時,頁面頂部顯示;在最大位置,底部顯示。我想重寫這種行爲。最小位置應顯示第一頁的頂部,最大位置應顯示最後一頁的底部。

在我遇到的死衚衕中:替換內置到JScrollPane中的ScrollBar;攔截由VScrollBar觸發的AdjustmentEvent;並研究ScrollDemo示例。這似乎是一個簡單的功能,但我一開始就卡住了。

有什麼建議嗎?謝謝!

+0

請看看你是否可以澄清你的問題或張貼的代碼片段演示您的問題 – ControlAltDel 2012-04-11 15:10:53

+0

我已經發布的示例代碼。我回答了這個問題,但事實上,仍然存在一個小問題。任何方式來重新將它指定爲「未答覆」? – 2012-04-14 21:49:59

回答

1

您是否希望能夠同時顯示第一頁的下半部分和第二頁的上半部分(並將元素從一頁拖到另一頁)?或者當時只有一個完整的頁面?

首先,您需要一個只顯示所有頁面並將其添加到JScrollPane的組件。你可能想讓它實現Scrollable接口來微調單元/塊滾動。

對於第二個,您可以在組件旁邊顯示單個(垂直)JScrollBar,並根據它的值更改顯示的頁面。在這種情況下,您使用更像滑塊控件的滾動條,並且頁面組件不是真正可滾動的(不使用JScrollPane)。

+0

兩者都沒有描述Adobe的PDF閱讀器的行爲。但第二個更接近:滾動條需要調整當前頁面的視圖,但一次不會顯示多個頁面。 – 2012-04-12 13:12:18

1

這似乎這樣的伎倆:

class DocumentScroller extends JScrollPane implements ChangeListener { 
    Component view ; 
    JPanel bookPanel, bookTop ; 
    ScrollingDocumentListener listener ; 
    Dimension pageSize ; 

    public DocumentScroller (Component view) { 
      this.view = view ; 
      } 

    public DocumentScroller (Component view, 
        int vsbPolicy, int hsbPolicy) { 
      super(vsbPolicy, hsbPolicy) ; 
      this.view = view ; 
      } 

    public void setViewportView (Component view) { 
      this.view = view ; 
      } 

    public void setPageCount (int pagect) { 
      if (view == null) 
        return ; 

      pageSize = view.getPreferredSize() ; 
      Dimension bookSize = new Dimension(pageSize) ; 
      bookSize.height *= pagect ; 

      bookPanel = new JPanel() ; 
      bookPanel.setLayout(new BorderLayout()) ; 
      bookPanel.setPreferredSize(bookSize) ; 
      bookPanel.add(bookTop = new JPanel(), 
          BorderLayout.NORTH) ; 
      bookPanel.add(view, BorderLayout.CENTER) ; 

      super.setViewportView(bookPanel) ; 
      getViewport().addChangeListener(this) ; 
      } 

    public void setUnitIncrement (int unitIncrement) { 
      getVerticalScrollBar().setUnitIncrement(unitIncrement) ; 
      } 

    public void setValue (int value) { 
      getVerticalScrollBar().setValue(value) ; 
      } 

    public void setScrollingDocumentListener (
        ScrollingDocumentListener listener) { 
      this.listener = listener ; 
      } 

    public void stateChanged (ChangeEvent e) { 
      try { 
        if (e.getSource().getClass() 
            != Class.forName(
             "javax.swing.JViewport")) 
          return ; 
        } 
      catch (Exception ex) { 
        return ; 
        } 

      Rectangle rect = ((JViewport) e.getSource() 
          ).getViewRect() ; 
      int offset = rect.y %pageSize.height ; 
      int pageTop = rect.y -offset ; 
      int pos = offset *rect.height /pageSize.height ; 

      bookTop.setPreferredSize(
          new Dimension(0, pageTop +pos)) ; 
      bookPanel.doLayout() ; 

      if (listener != null) 
        listener.setPage(pageTop /pageSize.height) ; 
      } 
    } 

interface ScrollingDocumentListener { 
    void setPage (int pageno) ; 
    } 
+0

這個代碼的問題是一個惱人的反彈效應。首先,顯示刷新滾動條動作。然後在stateChanged()上,「視圖」組件稍微向上移動並刷新顯示。解決方法是以某種方式攔截第一次刷新。 – 2012-04-14 21:51:43