2012-04-11 9 views
0

私は、ユーザーが定義済みのウィジェットを別のレイヤーにドラッグ&ドロップすることでPDFドキュメントにマークアップすることができるシンプルなアプリケーションを持っています。JScrollPaneの動作をオーバーライドする

私はJScollPaneを使用しています。ビューポートサイズは、単一の8.5x11ページに相当します。 VScrollBarが最小位置にあるとき、ページの上部が表示されます。最大位置では、下部が表示されます。私はこの動作を無効にしたいと思います。最小位置は最初のページの上部を表示し、最大ページは最後のページの下部を表示する必要があります。

私はヒットしました:JScrollPaneに組み込まれているScrollBarの置き換え。 VScrollBarによって発生したAdjustmentEventをインターセプトする。 ScrollDemoの例を勉強しています。これは簡単な機能のようですが、私は最初に立ち往生しています。

提案がありますか?ありがとう!

+0

あなたの質問を明確にまたは私は、サンプルコードを掲載している問題 – ControlAltDel

+0

を示すコードスニペットを投稿することができるかどうかを確認してください。私はこの質問に答えましたが、実際にはまだ小さな問題があります。これを「返答なし」と再指定する方法はありますか? –

答えて

1

第1ページの下半分と第2ページの上半分を同時に表示できるようにしたい(そして要素をあるページから別のページにドラッグする)ようにしたいですか?またはその時に完全な1ページだけ?

最初は、すべてのページを表示し、それをJScrollPaneに追加する単一のコンポーネントが必要です。ユニット/ブロックのスクロールを微調整するためにScrollableインターフェースを実装させたいと思うかもしれません。

2番目のコンポーネントでは、コンポーネントの横に単一の(垂直)JScrollBarを表示し、その値に応じて表示ページを変更できます。この場合、スライダコントロールのようなスクロールバーを使用し、ページコンポーネントは実際にはスクロールできません(JScrollPaneは使用されません)。

+0

どちらもAdobeのPDFリーダーの動作を説明していません。スクロールバーは現在のページのビューを調整する必要がありますが、一度に複数のページを表示することはありません。 –

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()で "view"コンポーネントが少し上に移動し、ディスプレイがリフレッシュされます。解決策は何とか最初のリフレッシュを傍受することです。 –

関連する問題