Question

I have an array of JTextPanes inside JScrollPanes. All those components I mentioned are inside a JPanel inside a JScrollPane.

User interface picture

At the start of the program, none of the JTextPanes have any text, so the scrollbars for them are not visible. The scrollbars for the JPanel are visible, because I have a lot of components in it.

My issue is that if the cursor is over one of the JTextPanes and I try to scroll, nothing happens because the computer thinks I want to scroll with the JTextPane's scrollbars. What I would like to happen is for the computer to realize that I'm trying to scroll with the JPanel's scrollbar. Is there any way I could accomplish this?

Thanks!

Edit:

You could produce a similar UI to the one above with this code ( this is the constructor of a class extending JFrame - apologies for ignoring a lot of good coding habits ):

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 );
}
Was it helpful?

Solution

The following code was taken as a quick hack from Mouse Wheel Controller.

Basically it intercepts the MouseWheelEvent for the scroll pane containing the text area. If the scrollbar is visible it redispatches the event back to the same scroll pane otherwise it finds the parent scrollPane and dispatches the event to that 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)
    {
//      System.out.println(e.getScrollType() + " : " + e.getScrollAmount() + " : " + e.getWheelRotation());
        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.getModifiersEx(),
            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);

                if (x == 0 && y ==0)
                {
                    textArea.append("1\n2\n3\n4\n5\n6\n7\n8\n9");
                    textArea.setCaretPosition(0);
                }

            }
        }

        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();
            }
        });
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top