使用更多逻辑ScrollBar进行Java滚动

时间:2013-08-16 01:27:03

标签: java swing mouseevent jscrollpane jscrollbar

我在JScrollPanes中有一个JTextPanes数组。我提到的所有组件都在JScrollPane内的JPanel中。

User interface picture

在程序开始时,没有任何JTextPanes有任何文本,因此它们的滚动条不可见。 JPanel的滚动条是可见的,因为我有很多组件。

我的问题是,如果光标位于其中一个JTextPanes上并且我尝试滚动,则没有任何反应,因为计算机认为我想使用JTextPane的滚动条滚动。我想要发生的是计算机意识到我正在尝试使用JPanel的滚动条滚动。有什么方法可以做到这一点吗?

谢谢!

编辑:

您可以使用此代码生成与上述类似的UI(这是扩展JFrame的类的构造函数 - 为忽略许多良好的编码习惯而道​​歉):

public JFrameTest() {
    JPanel panel = new JPanel( new GridLayout( 10 , 10 , 10 , 10 ) );
    for ( int i = 0 ; i < 10 ; i ++ ) {
        for ( int j = 0 ; j < 10 ; j ++ ) {
            JScrollPane paneToAdd = new JScrollPane( new JTextPane() ) {
                /**
                 * 
                 */
                private static final long serialVersionUID = 1L;

                @Override
                public Dimension getPreferredSize() {
                    return new Dimension( 100 , 100 );
                }
            };
            panel.add( paneToAdd );
        }
    }
    add( new JScrollPane( panel ) );

    setSize( 700 , 500 );
    setVisible( true );
    setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}

1 个答案:

答案 0 :(得分:2)

以下代码被视为来自Mouse Wheel Controller的快速破解。

基本上,它拦截包含文本区域的滚动窗格的MouseWheelEvent。如果滚动条可见,它会将事件重新分配回同一个滚动窗格,否则会找到父scrollPane并将事件调度到该scrollPane。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class MouseWheelToParent implements MouseWheelListener
{
    private JScrollPane scrollPane;
    private MouseWheelListener[] realListeners;

    public MouseWheelToParent(JScrollPane scrollPane)
    {
        this.scrollPane = scrollPane;
        install();
    }

    public void install()
    {
        if (realListeners != null) return;

        //  Keep track of original listeners so we can use them to
        //  redispatch an altered MouseWheelEvent

        realListeners = scrollPane.getMouseWheelListeners();

        for (MouseWheelListener mwl : realListeners)
        {
            scrollPane.removeMouseWheelListener(mwl);
        }

        //  Intercept events so they can be redispatched

        scrollPane.addMouseWheelListener(this);
    }

    /**
     *  Remove the class as the default listener and reinstall the original
     *  listeners.
     */
    public void uninstall()
    {
        if (realListeners == null) return;

        //  Remove this class as the default listener

        scrollPane.removeMouseWheelListener( this );

        //  Install the default listeners

        for (MouseWheelListener mwl : realListeners)
        {
            scrollPane.addMouseWheelListener( mwl );
        }

        realListeners = null;
    }

//  Implement MouseWheelListener interface

    /**
     *  Redispatch a MouseWheelEvent to the real MouseWheelListeners
     */
    public void mouseWheelMoved(MouseWheelEvent e)
    {
        JScrollPane scrollPane = (JScrollPane)e.getComponent();

        if (scrollPane.getVerticalScrollBar().isVisible())
        {
            //  Redispatch the event to original MouseWheelListener

            for (MouseWheelListener mwl : realListeners)
            {
                mwl.mouseWheelMoved( e );
            }
        }
        else
        {
            dispatchToParent(e, scrollPane);
            return;
        }
    }

    private void dispatchToParent(MouseWheelEvent e, JScrollPane scrollPane)
    {
        Component ancestor = SwingUtilities.getAncestorOfClass(JScrollPane.class, scrollPane);

        MouseWheelEvent mwe = new MouseWheelEvent(
            ancestor,
            e.getID(),
            e.getWhen(),
            e.getModifiers(),
            e.getX(),
            e.getY(),
            e.getXOnScreen(),
            e.getYOnScreen(),
            e.getClickCount(),
            e.isPopupTrigger(),
            e.getScrollType(),
            e.getScrollAmount(),
            e.getWheelRotation());

        ancestor.dispatchEvent(mwe);
    }

    private static void createAndShowUI()
    {
        JPanel panel = new JPanel( new GridBagLayout() );
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(10, 10, 10, 10);

        for (int y = 0; y < 10; y++)
        {
            for (int x = 0; x < 5; x++)
            {
                gbc.gridx = x;
                gbc.gridy = y;
                JTextArea textArea = new JTextArea(5, 20);
                JScrollPane scrollPane = new JScrollPane( textArea );
                scrollPane.setMinimumSize( scrollPane.getPreferredSize() );
                new MouseWheelToParent(scrollPane);
                panel.add(scrollPane, gbc);
            }
        }
        JFrame frame = new JFrame("TextAreaSSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new JScrollPane( panel ) );
        frame.setSize(400, 400);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}