Skip to main content

JXLayer 3.0 - MouseScrollableUI

Posted by alexfromsun on June 24, 2008 at 10:39 AM PDT

The mouse auto-scrolling is very popular these days for modern applications. I usually use this feature in the Firefox browser - you click the mouse wheel somewhere on the page and can immediately start scrolling.

A few months ago Kirill wrote an great review of the "auto-scrolling feature" implementation in Swing. I'd like to add one more item to the list.

Suppose you create a JTable, wrap it with JScrollPane and add it to a frame:

JScrollPane sp = JScrollPane(createMyTable());
add(sp); 

To enable auto-scrolling you just need to wrap a JScrollPane with JXLayer and set the MouseScrollableUI to it:

JScrollPane sp = JScrollPane(createMyTable());
JXLayer l = new JXLayer(sp, new MouseScrollableUI());       
add(l); 

After that you can you can activate auto-scrolling by clicking the mouse wheel:


src="http://java.sun.com/products/jfc/tsc/sightings/images/webstart.small.jpg">

demo screenshot

When the scrolling indicator appears, your can scroll by moving your mouse towards the desirable direction. Auto-scrolling is deactivated by clicking any keyboard or mouse button.

Implementation

Things like MouseScrollableUI are very easily implemented with JXLayer,
because it provides a way to catch all mouseEvents for all components inside a JXLayer.

class MyLayerUI extends AbstractLayerUI {
   
    // This method catches all focus, mouse and keyboard events
    // for the layer and all its subcomponents
    @Override
    public void eventDispatched(AWTEvent e, JXLayer l) {
        super.eventDispatched(e, l);
        System.out.println("AWTEvent is dispatched: " + e);
    }

    // Utility methods which are called from eventDispatched()
    // to provide a hook for catching particular type of events
    @Override
    protected void processMouseEvent(MouseEvent e, JXLayer l) {
        System.out.println("MouseEvent on component: " + e.getComponent());
    }
   
    @Override
    protected void processMouseMotionEvent(MouseEvent e, JXLayer l) {
        System.out.println("MouseMotionEvent on component: " + e.getComponent());
    }   
}

Once you have a way to catch all mouseEvents for all subcomponents, everything else is straightforward. The only specific details is the scrolling indicator, initially I thought to paint it, as usual, in the paintLayer() method.

However I realized that I want to change the mouse cursor when I move the mouse over scrolling indicator and the best solution is to implement it as a custom component, set a resize mouse cursor and place it at the layer's glassPane.

The source code of the MouseScrollableUI is quite compact, the MouseScrollableDemo
for the webstart demo is even shorter.

(the runnable link is above the screenshot)

See you on the JXLayer forum



Thanks

alexp

Related Topics >>

Comments

Hello Chrriis

Thank you for this valuable comment!
MouseScrollableUI is fixed and now supports this way of scrolling also
, please run the demo from this blog to check it out

Hello Maksym

Thanks

alexp

Great work, Alexander!

Hi Alexander, It would be nice if it had the other expected way of auto-scrolling: - pressing the middle mouse button. - dragging, which starts scrolling. - releasing to stop scrolling. You could check the implementation in Substance as an example ( http://www.pushing-pixels.org/?p=280 ). In any case, I am glad that you added auto-scrolling!