Swing/GridScrollAnimation のバックアップ(No.6)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/GridScrollAnimation へ行く。
- 1 (2012-08-13 (月) 16:28:05)
- 2 (2012-08-14 (火) 19:58:11)
- 3 (2012-12-07 (金) 18:08:41)
- 4 (2012-12-25 (火) 18:23:14)
- 5 (2014-12-12 (金) 15:16:35)
- 6 (2015-03-01 (日) 16:07:40)
- 7 (2017-01-13 (金) 15:16:17)
- 8 (2017-12-15 (金) 14:23:26)
- 9 (2019-07-09 (火) 13:44:45)
- 10 (2019-11-04 (月) 01:58:19)
- 11 (2021-05-27 (木) 16:29:37)
- title: GridLayoutとJScrollPaneを使ったグリッド単位での表示切り替え tags: [JScrollPane, JPanel, GridLayout, Animation] author: aterai pubdate: 2012-08-13T16:28:05+09:00 description: JPanelにGridLayoutでコンポーネントを追加し、これをJScrollPaneに配置して、グリッド単位での表示、スクロールアニメーションによる切り替えを行います。
概要
JPanel
にGridLayout
でコンポーネントを追加し、これをJScrollPane
に配置して、グリッド単位での表示、スクロールアニメーションによる切り替えを行います。
Screenshot
Advertisement
サンプルコード
class GridPanel extends JPanel implements Scrollable {
public static int cols = 3, rows = 4;
public static Dimension size = new Dimension(160 * cols, 120 * rows);
public GridPanel() {
super(new GridLayout(rows, cols, 0, 0));
//putClientProperty("JScrollBar.fastWheelScrolling", Boolean.FALSE);
}
@Override public Dimension getPreferredScrollableViewportSize() {
Dimension d = getPreferredSize();
return new Dimension(d.width / cols, d.height / rows);
}
@Override public int getScrollableUnitIncrement(
Rectangle visibleRect, int orientation, int direction) {
return orientation == SwingConstants.HORIZONTAL ?
visibleRect.width : visibleRect.height;
}
@Override public int getScrollableBlockIncrement(
Rectangle visibleRect, int orientation, int direction) {
return orientation == SwingConstants.HORIZONTAL ?
visibleRect.width : visibleRect.height;
}
@Override public boolean getScrollableTracksViewportWidth() {
return false;
}
@Override public boolean getScrollableTracksViewportHeight() {
return false;
}
@Override public Dimension getPreferredSize() {
return size;
}
}
class ScrollAction extends AbstractAction {
private static Timer scroller;
private final Point vec;
private final JScrollPane scrollPane;
public ScrollAction(String name, JScrollPane scrollPane, Point vec) {
super(name);
this.scrollPane = scrollPane;
this.vec = vec;
}
@Override public void actionPerformed(ActionEvent e) {
final JViewport vport = scrollPane.getViewport();
final JComponent v = (JComponent)vport.getView();
final int w = vport.getWidth(),
h = vport.getHeight(),
sx = vport.getViewPosition().x,
sy = vport.getViewPosition().y;
final Rectangle rect = new Rectangle(w, h);
if (scroller != null && scroller.isRunning()) return;
scroller = new Timer(5, new ActionListener() {
double MAX = 100d;
int count = (int) MAX;
@Override public void actionPerformed(ActionEvent e) {
double a = easeInOut(--count / MAX);
int dx = (int) (w - a * w + .5);
int dy = (int) (h - a * h + .5);
if (count <= 0) {
dx = w;
dy = h;
scroller.stop();
}
rect.setLocation(sx + vec.x * dx, sy + vec.y * dy);
v.scrollRectToVisible(rect);
}
});
scroller.start();
}
private static double easeInOut(double t) {
//range: 0.0<=t<=1.0
if (t < .5) {
return .5 * pow3(t * 2d);
} else {
return .5 * (pow3(t * 2d - 2d) + 2d);
}
}
private static double pow3(double a) {
//return Math.pow(a, 3d);
return a * a * a;
}
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、GridLayout
を使ってグリッド状に配置したコンポーネントを、JScrollPane
とscrollRectToVisible(...)
メソッドで、グリッド単位の表示と切り替え(スクロールアニメーション付き)を行なっています。
- 最初に表示されるコンポーネントは、左上にある(一番最初に
JPanel
に追加した)コンポーネント PreferredScrollableViewportSize
の変更(グリッドのサイズ変更)には対応していないJScrollPane
の各スクロールバーは常に非表示なので、マウスホイールによるスクロールには対応していない- フォーカスの移動に表示切り替えは対応していない
CardLayout
+スクロールアニメーションでも同様の動作が可能?