TITLE:JScrollPaneのスクロール量を変更

JScrollPaneのスクロール量を変更

編集者:Terai Atsuhiro~

作成日:2003-10-23
更新日:2021-03-19 (金) 00:45:26
  • category: swing folder: ScrollIncrement title: JScrollPaneのスクロール量を変更 tags: [JScrollPane, JScrollBar] author: aterai pubdate: 2003-12-01 description: スクロールがホイールの回転でスムーズに移動しない(遅い)場合は、JScrollPaneのスクロール量を変更します。 image: https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTSi6qpTZI/AAAAAAAAAi8/nrtWKpDCdHI/s800/ScrollIncrement.png

概要

スクロールがホイールの回転でスムーズに移動しない(遅い)場合は、JScrollPaneのスクロール量を変更します。

概要

スクロールがホイールの回転でスムーズに移動しない(遅い)場合は、JScrollPaneのスクロール量を変更します。

サンプルコード

#spanend
#spanadd
JScrollPane scroll = new JScrollPane();
#spanend
#spanadd
scroll.getVerticalScrollBar().setUnitIncrement(25);
#spanend
#spanadd
View in GitHub: Java, Kotlin

#screenshot

解説

JScrollPaneからスクロールバーを取得し、JScrollBar#setUnitIncrement(int)メソッドでユニット増分値(unitIncrement)を設定しています。

サンプルコード

JScrollPane scroll = new JScrollPane();
scroll.getVerticalScrollBar().setUnitIncrement(25);
  • WindowsLookAndFeelの場合、JScrollBar#putClientProperty("JScrollBar.fastWheelScrolling", Boolean.TRUE);を設定するとマウスホイールによるスクロールは高速化(デフォルトと同程度の速度)可能
  • JScrollBarUnitIncrementBlockIncrementについて
    • Mouse Wheel Controller « Java Tips Weblog
    • Windows 7環境でのe.getScrollAmount()のデフォルト値: 3
    • DesktopPropertyなどを経由せず、OSのコントロールパネルのマウスのプロパティを直接参照している模様?
  • How to Write a Mouse-Wheel Listener (The Java™ Tutorials > Creating a GUI With JFC/Swing > Writing Event Listeners)
    • scrollPane.getVerticalScrollBar().setBlockIncrement(...)を設定した場合、その設定した値とScroll amount(デフォルトの3固定) × unit increment(scrollPane.getVerticalScrollBar().getUnitIncrement(...))のより小さい方がホイールでのスクロール量となる
      • ただし、scrollPane.getVerticalScrollBar().setBlockIncrement(...)で設定した値がscrollPane.getVerticalScrollBar().getUnitIncrement(...) より小さい場合はUnitIncrement自体がホイールでのスクロール量となる
      • このため、例えば縦のアイテムを配置する通常のJListなどのホイールスクロールをスクロールバーの矢印ボタンクリックと同じ1行ごとにしたいなら、scrollPane.getVerticalScrollBar().setBlockIncrement(0)でも可能
      • すでに上限、下限近くまでスクロールして余地がない場合などは除く(限界を超えてスクロールなどはしない)
    • Scrollable#getScrollableUnitIncrement(...)などをオーバーライドしても、ホイールスクロールには関係ない?(カーソルキー用?)
    • JScrollBar#getClientProperty("JScrollBar.fastWheelScrolling")true(デフォルト)でViewJListなどのようにScrollableを実装している場合はScrollable#getScrollableUnitIncrement(...)Scrollable#getScrollableBlockIncrement(...)が使用されている
      • 詳細はBasicScrollPaneUI.Handlerを参照
    • マウスのプロパティで「1画面ずつスクロールする」にするとe.getScrollType()WHEEL_UNIT_SCROLLからWHEEL_BLOCK_SCROLLになり、上記の3行×スクロール量(BasicScrollBarUI.scrollByUnits(...))ではなくBasicScrollBarUI.scrollByBlock(...)が使用される
  • &jnlp;
  • &jar;
  • &zip;
    #spanend
    #spanadd
    import java.awt.*;
    #spanend
    #spanadd
    import java.awt.event.*;
    #spanend
    #spanadd
    import javax.swing.*;
    #spanend
    #spanadd
    import javax.swing.event.*;
    #spanend
    
    #spandel
    **解説 [#r4f1a8de]
    #spanend
    #spandel
    JScrollPaneからスクロールバーを取得し、これにsetUnitIncrementメソッドでユニット増分値(unitIncrement)を設定しています。
    #spanend
    #spanadd
    public class WheelScrollTest {
    #spanend
      public JComponent makeUI() {
        JList list = makeList();
        final JScrollPane scrollPane = new JScrollPane(list) {
          @Override protected void processMouseWheelEvent(MouseWheelEvent e) {
            MouseWheelEvent mwe = new MouseWheelEvent(
              e.getComponent(),
              e.getID(),
              e.getWhen(),
              e.getModifiers(),
              e.getX(), e.getY(),
              e.getXOnScreen(),
              e.getYOnScreen(),
              e.getClickCount(),
              e.isPopupTrigger(),
              e.getScrollType(),
              100, //e.getScrollAmount(),
              e.getWheelRotation());
            System.out.println("ScrollAmount: " + e.getScrollAmount());
            super.processMouseWheelEvent(mwe);
          }
        };
    
    #spandel
    **コメント [#dc87fe46]
    #spanend
        scrollPane.addMouseWheelListener(new MouseWheelListener() {
          @Override public void mouseWheelMoved(MouseWheelEvent e) {
            if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
              System.out.println("WHEEL_UNIT_SCROLL");
            } else if (e.getScrollType() == MouseWheelEvent.WHEEL_BLOCK_SCROLL) {
              System.out.println("WHEEL_BLOCK_SCROLL");
            }
          }
        });
    #spanadd
    
    #spanend
        list.setFixedCellHeight(64);
        scrollPane.getVerticalScrollBar().setUnitIncrement(32);
        scrollPane.getVerticalScrollBar().setBlockIncrement(64 * 6);
    #spanadd
    
    #spanend
        JViewport vp = scrollPane.getViewport();
        Scrollable view = (Scrollable) vp.getView();
        Rectangle vr = vp.getViewRect();
    #spanadd
    
    #spanend
        System.out.println(
            "FixedCellHeight: " + list.getFixedCellHeight());
        System.out.println(
            "getUnitIncrement: " + scrollPane.getVerticalScrollBar().getUnitIncrement(1));
        System.out.println(
            "getBlockIncrement: " + scrollPane.getVerticalScrollBar().getBlockIncrement(1));
        System.out.println(
            "getScrollableUnitIncrement: " + view.getScrollableUnitIncrement(
            vr, scrollPane.getVerticalScrollBar().getOrientation(), 1));
        System.out.println("getScrollableBlockIncrement: " + view.getScrollableBlockIncrement(
            vr, scrollPane.getVerticalScrollBar().getOrientation(), 1));
    #spanadd
    
    #spanend
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        final JSpinner spinner = new JSpinner(new SpinnerNumberModel(
            scrollPane.getVerticalScrollBar().getBlockIncrement(1), 0, 100000, 1));
        spinner.setEditor(new JSpinner.NumberEditor(spinner, "#####0"));
        spinner.addChangeListener(new ChangeListener() {
          @Override public void stateChanged(ChangeEvent e) {
            JSpinner s = (JSpinner) e.getSource();
            Integer iv = (Integer) s.getValue();
            //System.out.println(iv);
            scrollPane.getVerticalScrollBar().setBlockIncrement(iv);
          }
        });
        Box box = Box.createHorizontalBox();
        box.add(new JLabel("Block Increment:"));
        box.add(Box.createHorizontalStrut(2));
        box.add(spinner);
        box.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    #spanadd
    
    #spanend
        JPanel p = new JPanel(new BorderLayout());
        p.add(box, BorderLayout.NORTH);
        p.add(scrollPane);
        return p;
      }
      @SuppressWarnings("unchecked")
      private static JList makeList() {
        DefaultListModel model = new DefaultListModel();
        for (int i = 0; i < 100; i++) {
          model.addElement("Item: " + i);
        }
        JList list = new JList(model) {
    #spanadd
    //       @Override public int getScrollableUnitIncrement(
    #spanend
    #spanadd
    //           Rectangle visibleRect, int orientation, int direction) {
    #spanend
    #spanadd
    //         return 64;
    #spanend
    #spanadd
    //       }
    #spanend
    #spanadd
    //
    #spanend
    #spanadd
    //       @Override public int getScrollableBlockIncrement(
    #spanend
    #spanadd
    //           Rectangle visibleRect, int orientation, int direction) {
    #spanend
    #spanadd
    //         if (orientation == SwingConstants.VERTICAL) {
    #spanend
    #spanadd
    //           int inc = visibleRect.height;
    #spanend
    #spanadd
    //           /* Scroll Down */
    #spanend
    #spanadd
    //           if (direction > 0) {
    #spanend
    #spanadd
    //             // last cell is the lowest left cell
    #spanend
    #spanadd
    //             int last = locationToIndex(
    #spanend
    #spanadd
    //               new Point(visibleRect.x, visibleRect.y + visibleRect.height - 1));
    #spanend
    #spanadd
    //             if (last != -1) {
    #spanend
    #spanadd
    //               Rectangle lastRect = getCellBounds(last, last);
    #spanend
    #spanadd
    //               if (lastRect != null) {
    #spanend
    #spanadd
    //                 inc = lastRect.y - visibleRect.y;
    #spanend
    #spanadd
    //                 if ((inc == 0) && (last < getModel().getSize() - 1)) {
    #spanend
    #spanadd
    //                   inc = lastRect.height;
    #spanend
    #spanadd
    //                 }
    #spanend
    #spanadd
    //               }
    #spanend
    #spanadd
    //             }
    #spanend
    #spanadd
    //           }
    #spanend
    #spanadd
    //           /* Scroll Up */
    #spanend
    #spanadd
    //           else {
    #spanend
    #spanadd
    //             int newFirst = locationToIndex(
    #spanend
    #spanadd
    //               new Point(visibleRect.x, visibleRect.y - visibleRect.height));
    #spanend
    #spanadd
    //             int first = getFirstVisibleIndex();
    #spanend
    #spanadd
    //             if (newFirst != -1) {
    #spanend
    #spanadd
    //               if (first == -1) {
    #spanend
    #spanadd
    //                 first = locationToIndex(visibleRect.getLocation());
    #spanend
    #spanadd
    //               }
    #spanend
    #spanadd
    //               Rectangle newFirstRect = getCellBounds(newFirst, newFirst);
    #spanend
    #spanadd
    //               Rectangle firstRect = getCellBounds(first, first);
    #spanend
    #spanadd
    //               if ((newFirstRect != null) && (firstRect != null)) {
    #spanend
    #spanadd
    //                 while ( (newFirstRect.y + visibleRect.height <
    #spanend
    #spanadd
    //                      firstRect.y + firstRect.height) &&
    #spanend
    #spanadd
    //                     (newFirstRect.y < firstRect.y) ) {
    #spanend
    #spanadd
    //                   newFirst++;
    #spanend
    #spanadd
    //                   newFirstRect = getCellBounds(newFirst, newFirst);
    #spanend
    #spanadd
    //                 }
    #spanend
    #spanadd
    //                 inc = visibleRect.y - newFirstRect.y;
    #spanend
    #spanadd
    //                 if ((inc <= 0) && (newFirstRect.y > 0)) {
    #spanend
    #spanadd
    //                   newFirst--;
    #spanend
    #spanadd
    //                   newFirstRect = getCellBounds(newFirst, newFirst);
    #spanend
    #spanadd
    //                   if (newFirstRect != null) {
    #spanend
    #spanadd
    //                     inc = visibleRect.y - newFirstRect.y;
    #spanend
    #spanadd
    //                   }
    #spanend
    #spanadd
    //                 }
    #spanend
    #spanadd
    //               }
    #spanend
    #spanadd
    //             }
    #spanend
    #spanadd
    //           }
    #spanend
    #spanadd
    //           return 128;
    #spanend
    #spanadd
    //         }
    #spanend
    #spanadd
    //         return super.getScrollableBlockIncrement(visibleRect, orientation, direction);
    #spanend
    #spanadd
    //       }
    #spanend
        };
        list.setCellRenderer(new DefaultListCellRenderer() {
          private final Color ec = new Color(240, 240, 240);
          @Override public Component getListCellRendererComponent(
            JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            if (isSelected) {
              setForeground(list.getSelectionForeground());
              setBackground(list.getSelectionBackground());
            } else {
              setForeground(list.getForeground());
              setBackground(((index % 2 == 0)) ? ec : list.getBackground());
            }
            return this;
          }
        });
        return list;
      }
    #spanadd
    
    #spanend
      public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
          @Override public void run() {
            createAndShowGUI();
          }
        });
      }
    #spanadd
    
    #spanend
      public static void createAndShowGUI() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.getContentPane().add(new WheelScrollTest().makeUI());
        f.setSize(320, 240);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
      }
    #spanadd
    }
    #spanend
    #spanadd
    

参考リンク

コメント