Swing/ScrollIncrement のバックアップの現在との差分(No.11)
TITLE:JScrollPaneのスクロール量を変更
JScrollPaneのスクロール量を変更
編集者:Terai Atsuhiro~
作成日:2003-10-23
更新日:2021-03-19 (金) 00:45:26
概要
スクロールがホイールの回転でスムーズに移動しない(遅い)場合は、JScrollPane
のスクロール量を変更します。
Screenshot
Advertisement
概要
スクロールがホイールの回転でスムーズに移動しない(遅い)場合は、JScrollPaneのスクロール量を変更します。サンプルコード
#screenshot
解説
JScrollPane
からスクロールバーを取得し、JScrollBar#setUnitIncrement(int)
メソッドでユニット増分値(unitIncrement
)を設定しています。
サンプルコード
JScrollPane scroll = new JScrollPane(); scroll.getVerticalScrollBar().setUnitIncrement(25);
-
WindowsLookAndFeel
の場合、JScrollBar#putClientProperty("JScrollBar.fastWheelScrolling", Boolean.TRUE);
を設定するとマウスホイールによるスクロールは高速化(デフォルトと同程度の速度)可能 -
JScrollBar
のUnitIncrement
とBlockIncrement
について- 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
(デフォルト)でView
がJList
などのように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
参考リンク
- JScrollBar#setUnitIncrement(int) (Java Platform SE 8)
- Mouse Wheel Controller « Java Tips Weblog
- How to Write a Mouse-Wheel Listener (The Java™ Tutorials > Creating a GUI With JFC/Swing > Writing Event Listeners)