开发者

Java -- How to set the keyboard scroll speed for a JScrollPane

A JPanel has a JScrollPane that contains yet another JPanel or two. My life depends on increasing the scroll speed using a keyboard's directional arrows. After careful deliberation, the powers that be decided that: sc.getVerticalScrollBar().setUnitIncrement(240); 开发者_JAVA百科should only be applicable to a mouse, in a clever ruse to elicit minor annoyances amongst java developers. Is there anything that can be done to increase scroll speed? My life hangs in the balance.


You have to use a combination of InputMap.put and ActionMap.put to capture the keyboard events for the components contained on your JScrollPane and process the keyboard events when the JScrollPane has the focus. Since the default increment value for scrolling is 1 you should add or substract the desired increment value to the current value of the scrollbar for JScrollPane which you can get with JScrollPane.getVerticalScrollBar().getValue() and set with JScrollPane.getVerticalScrollBar().setValue(int).

An example of capturing events for the contained elements withing JScrollPane can be done with this code, I've done with buttons, but you get the point (Sorry for the bad organization of the code):

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

public class Test
{
    public static void main(String[] args)
    {
        final JFrame f = new JFrame("");
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(2000,1));


        for(int  i = 0; i != 2000; i++)
        {
            JButton btn = new JButton("Button 2");
            panel.add(btn);
        }
        final JScrollPane sPane = new JScrollPane(panel);
        final int increment = 5000;
        sPane.getVerticalScrollBar().setUnitIncrement(increment);

        KeyStroke kUp = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0);
        KeyStroke kDown = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0);

        sPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(kUp,"actionWhenKeyUp");
        sPane.getActionMap().put("actionWhenKeyUp",
            new AbstractAction("keyUpAction")
            {
                public void actionPerformed(ActionEvent e)
                {
                    final JScrollBar bar = sPane.getVerticalScrollBar();
                    int currentValue = bar.getValue();
                    bar.setValue(currentValue - increment);
                }
            }
        );

        sPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(kDown,"actionWhenKeyDown");
        sPane.getActionMap().put("actionWhenKeyDown",
            new AbstractAction("keyDownAction")
            {
                public void actionPerformed(ActionEvent e)
                {
                    final JScrollBar bar = sPane.getVerticalScrollBar();
                    int currentValue = bar.getValue();
                    bar.setValue(currentValue + increment);
                }
            }
        );
        f.add(sPane);
        f.pack();



        SwingUtilities.invokeLater(
                new Runnable()
                {
                    public void run()
                    {
                        f.setVisible(true);
                    }
                }
            );
    }
}

We register to listen and process that event with:

sPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(kUp,"actionWhenKeyUp");
sPane.getActionMap().put("actionWhenKeyUp",
    new AbstractAction("keyUpAction")
    {
        public void actionPerformed(ActionEvent e)
        {
            final JScrollBar bar = sPane.getVerticalScrollBar();
            int currentValue = bar.getValue();
            bar.setValue(currentValue - increment);
        }
    }
);

The key code that perform the value of JScrollBar increment is of the AbstractAction (in this case when the user press the up key).

        public void actionPerformed(ActionEvent e)
        {
            final JScrollBar bar = sPane.getVerticalScrollBar();
            int currentValue = bar.getValue();
            bar.setValue(currentValue - increment);
        }

What you should do is to complete the events when your JScrollPane has the focus, but that should be trivial.

Hope it helps to save your life :P or at least serve you as a starting point.


Probably not what you are looking for but you can use the Mouse Wheel Controller to speed up the scrolling when using a mouse.

My life depends on increasing the scroll speed using a keyboard's directional arrows.

Not sure what how you are getting the scroll pane to scroll when you use the keyboard. I can't get the scroll pane to scroll when I use the keyboard arrows. Post your SSCCE that demonstrates the problem.

Edit:

For my simple test I was just adding a JLabel to the scrollpane. Since a JLabel isn't focusable by default no component in the scrollpane had focus, so the default Actions for the scrollbars where not being invoked. By making the label focusable, the keyboard scrolling works.


import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.event.MouseInputAdapter;

public class testeSLider extends JFrame {
    private JPanel jp;
    private JScrollPane sc;

    public testeSLider() {
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setResizable(false);
        setLocationRelativeTo(null);
        setSize(new Dimension(820, 130));
        setBackground(Color.BLACK);
        jp = new JPanel();
        sc = new JScrollPane(jp);
        jp.setBackground(Color.GRAY);

        sc.setBounds(0, 0, 100, 400);
        sc.setBackground(Color.DARK_GRAY);
        sc.getHorizontalScrollBar().setPreferredSize(new Dimension(0, 0));
        sc.setBounds(50, 30, 300, 50);

        getContentPane().add(sc);

        int x = 0;
        for (int i = 0; i < 50; i++) {
            JPanel item = new JPanel();
            x = (87 * i) + (i * 10);

            item.setBackground(Color.getHSBColor(new Random().nextInt(255),
                    new Random().nextInt(255), new Random().nextInt(255)));
            item.setBounds(x, 5, 0, 0);
            item.setPreferredSize(new Dimension(90, 90));
            jp.add(item);
            addEfeito(item);
        }

    }

    private void addEfeito(JPanel item) {

        MouseInputAdapter adapter = new MouseInputAdapter() {
            private JPanel panelTmp;
            private int deslocamento = 3;
            private int mouseStartX;
            private int mouseStartY;

            @Override
            public void mouseDragged(MouseEvent e) {

                final JScrollBar bar = sc.getHorizontalScrollBar();
                int currentValue = bar.getValue();
                bar.setValue(currentValue + (mouseStartX - e.getX()));
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                panelTmp = ((JPanel) e.getSource());
                panelTmp.setBounds(panelTmp.getX(), panelTmp.getY(),
                        panelTmp.getWidth() + deslocamento,
                        panelTmp.getHeight() + deslocamento);

            }

            @Override
            public void mouseExited(MouseEvent e) {
                panelTmp = ((JPanel) e.getSource());

                panelTmp.setBounds(panelTmp.getX(), panelTmp.getY(),
                        panelTmp.getWidth() - deslocamento,
                        panelTmp.getHeight() - deslocamento);

            }

            @Override
            public void mouseClicked(MouseEvent e) {
                mouseStartX = e.getX();
                mouseStartY = e.getY();
            }

            @Override
            public void mousePressed(MouseEvent e) {
                mouseStartX = e.getX();
                mouseStartY = e.getY();
            }

            @Override
            public void mouseReleased(MouseEvent e) {

            }
        };
        item.addMouseListener(adapter);
        item.addMouseMotionListener(adapter);

    }

    public static void main(String args[]) {
        new testeSLider();
    }

}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜