---
category: swing
folder: ListMoveRow
title: JListの選択アイテムをJToolBarに配置したJButtonで上下に移動する
tags: [JList, JToolBar, JButton]
author: aterai
pubdate: 2023-05-22T02:47:48+09:00
description: JListの選択アイテムをJToolBarに配置したJButtonをクリックして上下に移動します。
image: https://drive.google.com/uc?id=1waKjbKioCjx9-YGyfSwPbmo5LMLpfzvM
hreflang:
    href: https://java-swing-tips.blogspot.com/2023/09/move-selected-item-in-jlist-up-or-down.html
    lang: en
---
* 概要 [#summary]
`JList`の選択アイテムを`JToolBar`に配置した`JButton`をクリックして上下に移動します。

#download(https://drive.google.com/uc?id=1waKjbKioCjx9-YGyfSwPbmo5LMLpfzvM)

* サンプルコード [#sourcecode]
#code(link){{
JButton up = new JButton("▲");
up.setFocusable(false);
up.addActionListener(e -> {
  int[] pos = list.getSelectedIndices();
  if (pos.length == 0) {
    return;
  }
  boolean isShiftDown = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
  int index0 = isShiftDown ? 0 : Math.max(0, pos[0] - 1);
  int idx = index0;
  for (int i : pos) {
    model.add(idx, model.remove(i));
    list.addSelectionInterval(idx, idx);
    idx++;
  }
  // scroll
  Rectangle r = list.getCellBounds(index0, index0 + pos.length);
  list.scrollRectToVisible(r);
});

JButton down = new JButton("▼");
down.setFocusable(false);
down.addActionListener(e -> {
  int[] pos = list.getSelectedIndices();
  if (pos.length == 0) {
    return;
  }
  boolean isShiftDown = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0;
  int max = model.getSize();
  int index = isShiftDown ? max : Math.min(max, pos[pos.length - 1] + 1);
  int index0 = index;
  // copy
  for (int i : pos) {
    int idx = Math.min(model.getSize(), ++index);
    model.add(idx, model.get(i));
    list.addSelectionInterval(idx, idx);
  }
  // clean
  for (int i = pos.length - 1; i >= 0; i--) {
    model.remove(pos[i]);
  }
  // scroll
  Rectangle r = list.getCellBounds(index0 - pos.length, index0);
  list.scrollRectToVisible(r);
});
}}

* 解説 [#explanation]
`DefaultListModel`には[https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/table/DefaultTableModel.html#moveRow-int-int-int- DefaultTableModel(int start, int end, int to)]のような移動メソッドは用意されていないので、以下のように`DefaultListModel<E>#get(index)`、`DefaultListModel<E>#remove(index)`、`DefaultListModel<E>#add(index,E)`メソッドを組み合わせて選択アイテムの上下移動を実行します。

- `JButton up = new JButton("▲")`
-- `JList`の選択アイテムをひとつ上に移動する
-- KBD{Shift}キーを押しながら`up`ボタンをクリックすると先頭位置(`index = 0`)まで選択アイテムを移動
-- 複数選択されている場合はもっとも上で選択されたアイテムのひとつ上(`list.getSelectedIndices()[0] - 1`)にまとめて移動
-- `DefaultListModel<E>#remove(index)`で選択アイテムの削除と取得を実行し、これを`DefaultListModel<E>#add(E)`で目的となる`index`に挿入することで上方向に移動
- `JButton down = new JButton("▼")`
-- `JList`の選択アイテムをひとつ下に移動する
-- KBD{Shift}キーを押しながら`down`ボタンをクリックすると末尾位置(`index = DefaultListModel<E>#getSize()`)まで選択アイテムを移動
-- 複数選択されている場合はもっとも下で選択されたアイテムのひとつ下(`list.getSelectedIndices()[length - 1] + 1`)にまとめて移動
-- `DefaultListModel<E>#get(index)`で選択アイテムを取得し、これを`DefaultListModel<E>#add(E)`で目的となる`index`に複写、その後で選択アイテムを下から順に削除することで下方向に移動
-- `DefaultListModel<E>#get(index)`で選択アイテムを取得し、これを`DefaultListModel<E>#add(index,E)`で目的となる`index`に複写、その後で選択アイテムを下から順に削除することで下方向に移動
-- [[TransferHandlerを使ったJListのドラッグ&ドロップによる並べ替え>Swing/DnDReorderList]]と同様の移動方法

* 参考リンク [#reference]
- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/DefaultListModel.html DefaultListModel (Java Platform SE 8)]
-- `DefaultListModel`に[https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/table/DefaultTableModel.html#moveRow-int-int-int- DefaultTableModel#moveRow(int start, int end, int to)]メソッドをコピーして[[JTableの行を移動>Swing/MoveRow]]のように移動する方法もある
- [[TransferHandlerを使ったJListのドラッグ&ドロップによる並べ替え>Swing/DnDReorderList]]

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