Results 1 to 8 of 8
  1. #1
    LittleRave is offline Member
    Join Date
    Dec 2009
    Location
    germany
    Posts
    15
    Rep Power
    0

    Default how to set mousewheel and arrow button scroll speed equal

    I've experienced that when I set
    Java Code:
    scrollPane.getVerticalScrollBar().setUnitIncrement(50);
    I can change the scroll speed of a JScrollPane, but there's always a difference between scrolling with the mousewheel and scrolling with the arrow buttons of the scrollbar. With the arrow buttons I always geht 1/3 of the mousewheel scroll speed.
    Is there a way to set them equal?

  2. #2
    zweibieren is offline Senior Member
    Join Date
    Aug 2009
    Location
    Pittsburgh, PA
    Posts
    284
    Rep Power
    5

    Default

    It will interfere with user expectations if you tinker with the amount of wheel scrolling.
    That said, here's a version of JScrollPane that has a method, setUnitsToScroll(int),
    that sets the number of "units" that the mouse wheel moves.
    Typically, a unit is one line of text.

    Java Code:
    /*
     *
    cryptic comment in JavaDocs for MouseWheelListener:
    				The MouseWheelEvent offers methods for conforming
    				to the underlying platform settings. These platform settings
    				can be changed at any time by the user.
    				MouseWheelEvents reflect the most recent settings.
    http://java.sun.com/docs/books/tutorial/uiswing/events/mousewheellistener.html
    				The amount that the mouse wheel scrolls is also platform dependent.
    				 Both the type and amount of scrolling may be settable
    				 via the mouse control panel for your platform.
     *
     */
    
    package Test;
    
    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.event.MouseWheelEvent;
    import java.awt.event.MouseWheelListener;
    import javax.swing.*;
    
    /**
         A hacked version of JScrollPane that permits modification of MouseWheelEvents.
     * In particular, the getUnitsToScroll() method can return an arbitrary amount.
     */
    public class HansackedScrollPane extends JScrollPane implements MouseWheelListener {
    
    	public HansackedScrollPane() { 
    		super();
    	}
    
    	int unitsToScroll = 0;
    	int getUnitsToScroll() { return unitsToScroll; }
    	void setUnitsToScroll(int units) { unitsToScroll = units; }
    
    	@Override
    	public void addNotify() {
    		super.addNotify();
    		mangleWheel();
    	}
    
    	MouseWheelListener[] realListeners;
    	/**
    	 * Intercept mouse wheel events so we can tinker with getUnitsToScroll()
    	 */
    	private void mangleWheel() {
    		realListeners = getMouseWheelListeners();
    		for (MouseWheelListener mwl : realListeners)
    			removeMouseWheelListener(mwl);
    		addMouseWheelListener(this);
    	}
    
    	public void mouseWheelMoved(MouseWheelEvent e) {
    		// System.out.println("wheel rolled " + e.getWheelRotation());
    		MouseWheelEvent mwe = new WheelHack(e);
    		for (MouseWheelListener mwl : realListeners)
    			mwl.mouseWheelMoved(mwe);
    	}
    	/**
    	 * A clone of MouseWheelEvent with modified getUnitsToScroll()
    	 */
    	class WheelHack extends MouseWheelEvent {
    		private WheelHack(MouseWheelEvent e) {
    			super((Component)e.getSource(), e.getID(),
    					e.getWhen(), e.getModifiers(),
    					e.getX(), e.getY(), e.getXOnScreen(), e.getYOnScreen(),
    					e.getClickCount(), e.isPopupTrigger(),
    					e.getScrollType(), e.getScrollAmount(),
    					e.getWheelRotation());
    		}
    		@Override
    		public int getUnitsToScroll() {
    			if (unitsToScroll == 0)   // not set by client yet, use system value
    				unitsToScroll = super.getUnitsToScroll();
    			return unitsToScroll;
    		}
    	}
    
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
    		// some text to scroll
    		JTextArea text = new JTextArea();
    		for (int i = 0; i < 1000; i++)
    			text.append("" + i + "\n");
    
    		// create scrollpane to be tested
    		final HansackedScrollPane subject = new HansackedScrollPane();
    		subject.setUnitsToScroll(25);
    		subject.setViewportView(text);
    
    		javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
    				// create and run frame
    				JFrame frame = new JFrame("ScrollTest");
    				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    				frame.setContentPane(subject);
    				frame.setPreferredSize(new Dimension(91, 500));
    				frame.pack();
    				frame.setVisible(true);
                }
            });
        }
    }

  3. #3
    LittleRave is offline Member
    Join Date
    Dec 2009
    Location
    germany
    Posts
    15
    Rep Power
    0

    Default

    But this won't adjust the scroll speed of the arrow buttons, will it? I want to speed them both up, but have them at the same speed

  4. #4
    zweibieren is offline Senior Member
    Join Date
    Aug 2009
    Location
    Pittsburgh, PA
    Posts
    284
    Rep Power
    5

    Default

    But this won't adjust the scroll speed of the arrow buttons, will it? I want to speed them both up, but have them at the same speed
    Give someone the moon and they want the sun ;-)
    This is it for me this year.
    Cheers until twenty-ten.

    Java Code:
    /*
    
     * This demo show how to adjust the scroll amount for ARROW and WHEEL
    
     	set ARROW_SCROLL_PIXELS to a number of pixels
    				to scroll for clicking an arrow at the end of a scrollbar
    	set WHEEL_SCROLL_PIXELS to a number of pixels
    				to scroll each time the mouse wheel is rolled one click
    
     * BACKGROUND - the way scrolling usually works
     *
     * There are four scrolling operations:
     *   -- BAR - click above or below the thumb in the scrollbar
     *   -- PAGE - pageup/pagedown buttons    ("scrollUp" action)
     *   -- ARROW - click an arrow at top or bottom of scrollbar
     *   -- WHEEL - roll the mouse wheel
     *
     * Of these, BAR and PAGE scroll by getScrollableBlockIncrement()
     *			For JTextArea, this is the height of the screen space.
     * ARROW scrolls by Scrollable.getScrollableUnitIncr()
     *			For JTextArea this is the getRowHeight()
     * WHEEL scrolls by a mutiple of Scrollable.getScrollableUnitIncr
     *       (the multiple is specified by the user on the control panel (not in Java)
    
     
     * The file below has two JComponents and an interface.
     * (They should be in three separate files instead of all nested in one.)
     * They are:
     * 
     *    class HansackedScrollPane extends JScrollPane
     *			The constructor has an argument which is 
     *			the number of pixels to scroll for a mouse wheel roll of one click.
     *			This number is only approximate unless the object
     *			being scrolled implements the interface WackyScrollUnit.
     * 
     *    interface WackyScrollUnit
     *			A JComponent that implements this interface
     *			will do a more accurate job of scrolling exactly the number
     *			of pixels specified for wheel scrolls. It must also override
     *			getScrollableUnitIncrement
     *
     *   class HansackedTextArea extends JTextArea
     *			The constructor has a parameter to specify
     *			the number of pixels to be scrolled
     *			for each click on the arrows in a scrollbar.
    
     */
    
    package Test;
    
    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.Rectangle;
    import java.awt.event.MouseWheelEvent;
    import java.awt.event.MouseWheelListener;
    import javax.swing.*;
    
    /**
         A hacked version of JScrollPane that permits modification of MouseWheelEvents.
     *  The amount to scroll for a wheel rool-click is specified in the constructor.
     */
    public class HansackedScrollPane extends JScrollPane implements MouseWheelListener {
    
    	Scrollable scrollee = null;
    
    	int wheelUnitsIncr;
    	int getUnitsForWheelStep() { return wheelUnitsIncr; }
    	void setUnitsForWheelStep(int units) { wheelUnitsIncr = units; }
    
    	/**
    	 * Construct a JScrollPane with non-standard scrolling by the mouse wheel.
    	 * @param u
    	 */
    	public HansackedScrollPane(int u) {
    		super();
    		wheelUnitsIncr = u;
    	}
    
    	@Override
    	public void setViewportView(Component view) {
    		if (view instanceof Scrollable)
    			scrollee = (Scrollable)view;
    		super.setViewportView(view);
    	}
    
    	@Override
    	public void addNotify() {
    		super.addNotify();
    		mangleWheel();
    	}
    
    	MouseWheelListener[] realListeners;
    	/**
    	 * Intercept mouse wheel events so we can tinker with getUnitsToScroll()
    	 */
    	private void mangleWheel() {
    		realListeners = getMouseWheelListeners();
    		for (MouseWheelListener mwl : realListeners)
    			removeMouseWheelListener(mwl);
    		addMouseWheelListener(this);
    	}
    
    	public void mouseWheelMoved(MouseWheelEvent e) {
    		// System.out.println("wheel rolled " + e.getWheelRotation());
    		MouseWheelEvent mwe 
    				= (scrollee == null) ? e : new WheelHack(e);
    		for (MouseWheelListener mwl : realListeners)
    			mwl.mouseWheelMoved(mwe);
    	}
    	/**
    	 * A clone of MouseWheelEvent that forces a block scroll
    	 */
    	class WheelHack extends MouseWheelEvent {
    		private WheelHack(MouseWheelEvent e) {
    			super((Component)e.getSource(), e.getID(),
    					e.getWhen(), e.getModifiers(),
    					e.getX(), e.getY(), e.getXOnScreen(), e.getYOnScreen(),
    					e.getClickCount(), e.isPopupTrigger(),
    
    					MouseWheelEvent.WHEEL_UNIT_SCROLL,		//	instead of e.getScrollType(),
    					computeDistance(e),											//  instead of e.getScrollAmount(),
    					e.getWheelRotation() < 0 ? -1 : 1);					// instead of e.getWheelRotation());
    		}
    	}
    
    	// helper for WheelHack
    	int computeDistance(MouseWheelEvent e) {
    		if (scrollee instanceof WackyScrollUnit) {
    			((WackyScrollUnit)scrollee).setTempUnit(wheelUnitsIncr);
    			return 1;
    		}
    
    		// return  floor(total / scrollable.getScrollableUnitIncrement())
    		int direction = e.getWheelRotation() < 0 ? -1 : 1;
    		int unitIncr = scrollee.getScrollableUnitIncrement(
    				getViewport().getViewRect(),
    				SwingConstants.VERTICAL, direction);
    		return wheelUnitsIncr/unitIncr;
    	}
    
    	/**
     *			A JComponent that implements this interface
     *			will do a more accurate job of scrolling exactly the number
     *			of pixels specified for wheel scrolls. It must also override
     *			getScrollableUnitIncrement
    	 */
    	interface WackyScrollUnit {
    		void setTempUnit(int u);
    		//public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction);
    	}
    
    	/**
     *			The constructor has a parameter to specify
     *			the number of pixels to be scrolled
     *			for each click on the arrows in a scrollbar.
    	 *
    	 *		The setTempUnit method helps with mouse wheelk scrolling
    	 */
    	static class HansackedTextArea extends JTextArea implements WackyScrollUnit {
    
    		int unitsIncr;
    		int getUnitsIncr() { return unitsIncr; }
    		void setUnitsIncr(int u) { unitsIncr = u; }
    
    		boolean tempUnitSet = false;   // if true, getScrollableUnitIncrement responds with tempUnit, once
    		int tempUnit;								// phoney value to return from getScriollableUnitIncrement
    		public void setTempUnit(int u) {
    			tempUnitSet = true;
    			tempUnit = u;
    		}
    
    		HansackedTextArea(int u) {
    			super();
    			unitsIncr = u;
    		}
    		@Override
    		public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
    			if (tempUnitSet) {
    				tempUnitSet = false;
    				return tempUnit;
    			}
    			return unitsIncr;  // pixels to scroll for a unit (an ARROW scroll)
    		}
    		@Override
    		public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
    			if (orientation != SwingConstants.VERTICAL)
    				return super.getScrollableBlockIncrement(visibleRect, orientation, direction);
    			return visibleRect.height;    // pixels to scroll   for PAGE and BAR
    		}
    	}
    
    	// parameters for scrolling
    	final static int ARROW_SCROLL_PIXELS = 91;
    	final static int WHEEL_SCROLL_PIXELS = 200;
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
    		// some text to scroll
    		JTextArea text;
    		text = new HansackedTextArea(ARROW_SCROLL_PIXELS);
    		for (int i = 0; i < 1000; i++)
    			text.append("" + i + "\n");
    
    		// create scrollpane to be tested
    		final HansackedScrollPane subject
    				= new HansackedScrollPane(WHEEL_SCROLL_PIXELS);
    		subject.setViewportView(text);
    
    		javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
    				// create and run frame
    				JFrame frame = new JFrame("ScrollTest");
    				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    				subject.setBorder(BorderFactory.createEmptyBorder(2,5,2,0));
    				frame.setContentPane(subject);
    				frame.setPreferredSize(new Dimension(45, 500));
    				frame.pack();
    				frame.setVisible(true);
                }
            });
        }
    
    }

  5. #5
    LittleRave is offline Member
    Join Date
    Dec 2009
    Location
    germany
    Posts
    15
    Rep Power
    0

    Default

    Give someone the moon and they want the sun ;-)
    It's winter! Who doesn't want the sun? :D
    Thanks a lot, will have a look at it when I solved my current problem.

  6. #6
    LittleRave is offline Member
    Join Date
    Dec 2009
    Location
    germany
    Posts
    15
    Rep Power
    0

    Default

    Hmm... I don't have a JTextArea but a JPanel in my JScrollPane, so I can't override the getScrollableUnitIncrement function, that's why it's not working ...

  7. #7
    camickr is offline Senior Member
    Join Date
    Jul 2009
    Posts
    1,233
    Rep Power
    7

    Default

    I don't have a JTextArea but a JPanel in my JScrollPane, so I can't override the getScrollableUnitIncrement function, that's why it's not working
    Sure you can. You can implement the Scrollable interface on any component. ScrollablePanel provides a generic solution and is easily customizable.

    @zweibieren - in about 3 weeks my next blog entry will be on a "Mouse Wheel Controller", which uses some of the concepts you introduced in your first solution to control the mouse wheel scroll amount. I will be giving you credit for some of the ideas in case you want to check it out.

  8. #8
    LittleRave is offline Member
    Join Date
    Dec 2009
    Location
    germany
    Posts
    15
    Rep Power
    0

    Default

    I cannot extend from ScrollablePanel class because I've already extended from JLayeredPane. I have to paint something in front of all added components of the panel so this is necessary, isn't it?.
    But I will try to make use of the Scrollable interface.
    Thanks for the suggestion :).


    EDIT: I've realized that JLayeredPane only works with a null layout, so I can't use it and found a different solution ... Now when I get back to this issue I'm gonna try the ScrollablePanel extension. Thanks again
    Last edited by LittleRave; 12-30-2009 at 03:04 PM.

Similar Threads

  1. ComparisonFailure on equal(to the eye) strings
    By staffan in forum New To Java
    Replies: 2
    Last Post: 03-12-2009, 02:57 PM
  2. Arrow Button Example
    By Java Tip in forum SWT
    Replies: 0
    Last Post: 07-11-2008, 04:44 PM
  3. Draw an arrow
    By Albert in forum SWT / JFace
    Replies: 3
    Last Post: 02-01-2008, 08:11 AM
  4. checking if there are equal numbers
    By nalinda in forum New To Java
    Replies: 1
    Last Post: 11-18-2007, 06:21 AM
  5. checking if there are equal numbers
    By nalinda in forum New To Java
    Replies: 0
    Last Post: 11-18-2007, 02:13 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •