Swing/ScrollIncrement の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/ScrollIncrement へ行く。
- Swing/ScrollIncrement の差分を削除
---
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
---
* 概要 [#summary]
スクロールがホイールの回転でスムーズに移動しない(遅い)場合は、`JScrollPane`のスクロール量を変更します。
#download(https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTSi6qpTZI/AAAAAAAAAi8/nrtWKpDCdHI/s800/ScrollIncrement.png)
* サンプルコード [#sourcecode]
#code(link){{
JScrollPane scroll = new JScrollPane();
scroll.getVerticalScrollBar().setUnitIncrement(25);
}}
* 解説 [#explanation]
`JScrollPane`からスクロールバーを取得し、`JScrollBar#setUnitIncrement(int)`メソッドでユニット増分値(`unitIncrement`)を設定しています。
- `WindowsLookAndFeel`の場合、`JScrollBar#putClientProperty("JScrollBar.fastWheelScrolling", Boolean.TRUE);`を設定するとマウスホイールによるスクロールは高速化(デフォルトと同程度の速度)可能
- `JScrollBar`の`UnitIncrement`と`BlockIncrement`について
-- [https://tips4java.wordpress.com/2010/01/10/mouse-wheel-controller/ Mouse Wheel Controller « Java Tips Weblog]
-- `Windows 7`環境での`e.getScrollAmount()`のデフォルト値: `3`
-- `DesktopProperty`などを経由せず、`OS`のコントロールパネルのマウスのプロパティを直接参照している模様?
- [https://docs.oracle.com/javase/tutorial/uiswing/events/mousewheellistener.html 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(...)`が使用される
#code{{
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class WheelScrollTest {
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);
}
};
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");
}
}
});
list.setFixedCellHeight(64);
scrollPane.getVerticalScrollBar().setUnitIncrement(32);
scrollPane.getVerticalScrollBar().setBlockIncrement(64 * 6);
JViewport vp = scrollPane.getViewport();
Scrollable view = (Scrollable) vp.getView();
Rectangle vr = vp.getViewRect();
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));
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));
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) {
// @Override public int getScrollableUnitIncrement(
// Rectangle visibleRect, int orientation, int direction) {
// return 64;
// }
//
// @Override public int getScrollableBlockIncrement(
// Rectangle visibleRect, int orientation, int direction) {
// if (orientation == SwingConstants.VERTICAL) {
// int inc = visibleRect.height;
// /* Scroll Down */
// if (direction > 0) {
// // last cell is the lowest left cell
// int last = locationToIndex(
// new Point(visibleRect.x, visibleRect.y + visibleRect.height - 1));
// if (last != -1) {
// Rectangle lastRect = getCellBounds(last, last);
// if (lastRect != null) {
// inc = lastRect.y - visibleRect.y;
// if ((inc == 0) && (last < getModel().getSize() - 1)) {
// inc = lastRect.height;
// }
// }
// }
// }
// /* Scroll Up */
// else {
// int newFirst = locationToIndex(
// new Point(visibleRect.x, visibleRect.y - visibleRect.height));
// int first = getFirstVisibleIndex();
// if (newFirst != -1) {
// if (first == -1) {
// first = locationToIndex(visibleRect.getLocation());
// }
// Rectangle newFirstRect = getCellBounds(newFirst, newFirst);
// Rectangle firstRect = getCellBounds(first, first);
// if ((newFirstRect != null) && (firstRect != null)) {
// while ( (newFirstRect.y + visibleRect.height <
// firstRect.y + firstRect.height) &&
// (newFirstRect.y < firstRect.y) ) {
// newFirst++;
// newFirstRect = getCellBounds(newFirst, newFirst);
// }
// inc = visibleRect.y - newFirstRect.y;
// if ((inc <= 0) && (newFirstRect.y > 0)) {
// newFirst--;
// newFirstRect = getCellBounds(newFirst, newFirst);
// if (newFirstRect != null) {
// inc = visibleRect.y - newFirstRect.y;
// }
// }
// }
// }
// }
// return 128;
// }
// return super.getScrollableBlockIncrement(visibleRect, orientation, direction);
// }
};
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;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
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);
}
}
}}
* 参考リンク [#reference]
- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/JScrollBar.html#setUnitIncrement-int- JScrollBar#setUnitIncrement(int) (Java Platform SE 8)]
- [https://tips4java.wordpress.com/2010/01/10/mouse-wheel-controller/ Mouse Wheel Controller « Java Tips Weblog]
- [https://docs.oracle.com/javase/tutorial/uiswing/events/mousewheellistener.html How to Write a Mouse-Wheel Listener (The Java™ Tutorials > Creating a GUI With JFC/Swing > Writing Event Listeners)]
* コメント [#comment]
#comment
- `JScrollBar`の`UnitIncrement`と`BlockIncrement`についてのメモを追加。 -- &user(aterai); &new{2012-07-10 (火) 21:03:39};
#comment