TITLE:JScrollPane内にあるJTableなどで追加した行が可視化されるようにスクロールする
#navi(../)
#tags(JScrollPane, JViewport, JTable, JList, JTree)
RIGHT:Posted by &author(aterai); at 2012-09-10
* JScrollPane内にあるJTableなどで追加した行が可視化されるようにスクロールする [#i0ec10e7]
`JScrollPane`の`JViewport`内にある`JTable`、`JList`、`JTree`で、それぞれ追加された最終行が可視化されるようにスクロールします。

#download
#ref(https://lh3.googleusercontent.com/-t_4BD1mGUGk/UE1eF0Ead3I/AAAAAAAABSM/4a4aPSpMDM4/s800/ScrollRectToVisible.png)

** サンプルコード [#kcb0b4e6]
#code(link){{
model.addRow(new Object[] {date.toString(), model.getRowCount(), false});
int i = table.convertRowIndexToView(model.getRowCount()-1);
Rectangle r = table.getCellRect(i, 0, true);
table.scrollRectToVisible(r);
}}

** 解説 [#h5ca79e3]
- `JTable`
-- 追加した行の`0`列目のセル領域を取得して、`scrollRectToVisible`で可視化
-- ソートやフィルターが使用されている場合を考慮して、追加した行のインデックスを`JTable#convertRowIndexToView(int)`で変換してから、セル領域を取得

- `JList`
-- [http://docs.oracle.com/javase/jp/6/api/javax/swing/JList.html#ensureIndexIsVisible(int) JList#ensureIndexIsVisible(int)]を使って、追加した最終行を可視化(このメソッド内部で`scrollRectToVisible`を使用)

#code{{
Rectangle cellBounds = list.getCellBounds(index, index);
if(cellBounds != null) {
  list.scrollRectToVisible(cellBounds);
}
}}

- `JTree`
-- [http://docs.oracle.com/javase/jp/6/api/javax/swing/JTree.html#scrollRowToVisible(int) JTree#scrollRowToVisible(int)]、または[http://docs.oracle.com/javase/jp/6/api/javax/swing/JTree.html#scrollPathToVisible(javax.swing.tree.TreePath) JTree#scrollPathToVisible(TreePath)]で追加した最終行を可視化
-- `tree.scrollRowToVisible(row)`は `tree.scrollPathToVisible(tree.getPathForRow(row))`と同等
-- `JTree#scrollPathToVisible(TreePath)`は内部で、`tree.scrollRectToVisible(tree.getPathBounds(path))`を使用

#code{{
DefaultTreeModel treeModel = (DefaultTreeModel)tree.getModel();
DefaultMutableTreeNode parent   = (DefaultMutableTreeNode)treeModel.getRoot();
DefaultMutableTreeNode newChild = new DefaultMutableTreeNode(date);
treeModel.insertNodeInto(newChild, parent, parent.getChildCount());
/* //tree.scrollRowToVisible(row) == tree.scrollPathToVisible(tree.getPathForRow(row))
tree.scrollRowToVisible(tree.getRowCount()-1);
/*/
tree.scrollPathToVisible(new TreePath(newChild.getPath()));
//*/
}}

** 参考リンク [#pf4abfe7]
- [[JScrollPaneのViewportをマウスで掴んでスクロール>Swing/HandScroll]]
-- `JComponent#scrollRectToVisible(...)`を使用してスクロール
- [[JTextPaneで最終行に移動>Swing/CaretPosition]]
-- キャレットの移動でスクロール

** コメント [#x0728da5]
#comment