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
    285
    Rep Power
    11

    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
    285
    Rep Power
    11

    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,236
    Rep Power
    12

    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 Tips
    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
  •