【问题标题】:Java -- How to set the keyboard scroll speed for a JScrollPaneJava -- 如何为 JScrollPane 设置键盘滚动速度
【发布时间】:2016-04-01 22:21:51
【问题描述】:

一个JPanel 有一个JScrollPane 包含另一个JPanel 或两个。我的生活依赖于使用键盘的方向箭头提高滚动速度。经过深思熟虑,决定的权力是:sc.getVerticalScrollBar().setUnitIncrement(240); 应该只适用于鼠标,这是一个巧妙的诡计,在 Java 开发人员中引起轻微的烦恼。有什么办法可以提高滚动速度吗?我的生命悬而未决。

【问题讨论】:

    标签: java swing


    【解决方案1】:

    您必须使用InputMap.putActionMap.put 的组合来捕获JScrollPane 中包含的组件的键盘事件,并在JScrollPane 具有焦点时处理键盘事件。由于滚动的默认增量值为 1,您应该将所需的增量值添加或减去 JScrollPane 的滚动条的当前值,您可以使用 JScrollPane.getVerticalScrollBar().getValue() 获得并使用 JScrollPane.getVerticalScrollBar().setValue(int). 进行设置

    使用 JScrollPane 为包含的元素捕获事件的示例可以使用此代码完成,我已经完成了按钮,但您明白了(抱歉代码组织不当):

    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);
                        }
                    }
                );
        }
    }
    

    我们注册以监听和处理该事件:

    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);
            }
        }
    );
    

    执行JScrollBar递增值的关键代码是AbstractAction(在这种情况下,当用户按下向上键时)。

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

    您应该做的是在您的 JScrollPane 获得焦点时完成事件,但这应该是微不足道的。

    希望它有助于挽救您的生命:P 或者至少可以作为起点。

    【讨论】:

    • 嗯,您提供了 API 的链接,但您没有阅读 API 中的说明:“此方法现已过时,请结合使用 getActionMap() 和 getInputMap() 以获得类似的行为."。但是,使用键绑定是要走的路,所以 +1。
    • 很抱歉没有在我的回答中说明这一点。
    • 修复了已弃用的 API 用法
    【解决方案2】:

    可能不是您要查找的内容,但您可以使用 Mouse Wheel Controller 在使用鼠标时加快滚动速度。

    我的生活依赖于使用键盘的方向箭头提高滚动速度。

    不确定当您使用键盘时如何让滚动窗格滚动。当我使用键盘箭头时,我无法让滚动窗格滚动。发布您的SSCCE 来说明问题。

    编辑:

    对于我的简单测试,我只是在滚动窗格中添加了一个 JLabel。由于默认情况下 JLabel 不可聚焦,因此滚动窗格中的任何组件都没有焦点,因此未调用滚动条的默认操作。通过使标签可聚焦,键盘滚动工作。

    【讨论】:

      【解决方案3】:
      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();
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2016-06-14
        • 1970-01-01
        • 2012-04-24
        • 2012-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多