覆盖JScrollPane行为

时间:2012-04-11 15:08:27

标签: java swing jscrollpane

我有一个简单的应用程序,允许用户通过将预定义的小部件拖放到单独的图层来标记PDF文档。

我正在使用JScollPane。视口大小相当于单个8.5x11页面。当VScrollBar位于最小位置时,页面顶部显示;在最大位置,底部显示。我想覆盖这种行为。最小位置应显示在第一页的顶部,最大值应显示在最后一页的底部。

在我遇到的死胡同中:替换内置于JScrollPane中的ScrollBar;拦截VScrollBar触发的AdjustmentEvent;并研究ScrollDemo示例。这似乎是一个简单的功能,但我一开始就陷入困境。

有什么建议吗?谢谢!

2 个答案:

答案 0 :(得分:1)

您是否希望能够同时显示第一页的下半部分和第二页的上半部分(并将元素从一个页面拖动到另一个页面)?或者当时只有一个完整的页面?

首先,您需要一个只显示所有页面并将其添加到JScrollPane的组件。您可能希望让它实现Scrollable接口来微调单位/块滚动。

对于第二个,您只需在组件旁边显示单个(垂直)JScrollBar,并根据其值更改显示的页面。在这种情况下,您使用滚动条更像滑块控件,并且您的页面组件实际上不可滚动(不使用JScrollPane)。

答案 1 :(得分: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 ) ;
    }