Swing/DnDList のバックアップの現在との差分(No.3)
TITLE:JListの項目をドラッグ&ドロップ
JListの項目をドラッグ&ドロップ
編集者:Terai Atsuhiro~
作成日:2004-02-16
更新日:2022-10-20 (木) 21:25:19
概要
JList
をドラッグ&ドロップして項目を入れ替えます。
Screenshot
Advertisement
概要
JListをドラッグ&ドロップして、項目を入れ替えます。サンプルコード
#spanend
#spanadd
@Override protected void paintComponent(Graphics g) {
#spanend
super.paintComponent(g);
if (targetIndex >= 0) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setPaint(lineColor);
g2.fill(targetLine);
g2.dispose();
}
#spanadd
}
#spanend
#spandel
#screenshot
#spanend
#spanadd
private void initTargetLine(Point p) {
#spanend
Rectangle rect = getCellBounds(0, 0);
int cellHeight = rect.height;
int lineHeight = 2;
int modelSize = getModel().getSize();
targetIndex = -1;
targetLine.setSize(rect.width, lineHeight);
for (int i = 0; i < modelSize; i++) {
rect.setLocation(0, cellHeight * i - cellHeight / 2);
if (rect.contains(p)) {
targetIndex = i;
targetLine.setLocation(0, i * cellHeight);
break;
}
}
if (targetIndex < 0) {
targetIndex = modelSize;
targetLine.setLocation(0, targetIndex * cellHeight - lineHeight);
}
#spanadd
}
#spanend
#spandel
**サンプルコード [#kadf6356]
#spanend
private Rectangle2D raCueLine = new Rectangle2D.Float();
private Rectangle2D midArea = new Rectangle2D.Float();
public void dragOver(final DropTargetDragEvent e) {
Graphics2D g2 = (Graphics2D) list1.getGraphics();
int cellHeight = (int) list1.getCellBounds(0,0).getHeight();
int cellWidht = (int) list1.getCellBounds(0,0).getWidth();
boolean flag = false;
for(int i=0;i<=model.getSize();i++) {
midArea.setRect(0, cellHeight*i - (int) (cellHeight/2), cellWidht, cellHeight);
if(midArea.contains(e.getLocation())) {
flag = true;
targetIndex = i;
g2.setColor(lineColor);
}else{
g2.setColor(list1.getBackground());
}
raCueLine.setRect(0, i*cellHeight, cellWidht, 2);
g2.fill(raCueLine);
}
//セルの間にターゲットが無かった場合リストの一番下にラインを引く
if(!flag) {
targetIndex = model.getSize();
raCueLine.setRect(0, targetIndex*cellHeight, cellWidht, 2);
g2.setColor(lineColor);
g2.fill(raCueLine);
}
if(isDragAcceptable(e)) {
e.acceptDrag(e.getDropAction());
}else{
e.rejectDrag();
}
//選択がずれないように…
list1.setSelectedIndex(draggedIndex);
}
#spanadd
@Override public void dragOver(final DropTargetDragEvent e) {
#spanend
if (isDragAcceptable(e)) {
e.acceptDrag(e.getDropAction());
} else {
e.rejectDrag();
return;
}
initTargetLine(e.getLocation());
repaint();
#spanadd
}
#spanend
public void drop(DropTargetDropEvent e) {
Point point = e.getLocation();
Transferable t = e.getTransferable();
DataFlavor[] f = t.getTransferDataFlavors();
try {
if(isDropAcceptable(e)) {
Component comp = (Component) t.getTransferData(f[0]);
Object str = model.getElementAt(draggedIndex);
if(targetIndex==draggedIndex) {
list1.setSelectedIndex(targetIndex);
}else if(targetIndex<draggedIndex) {
model.removeElementAt(draggedIndex);
model.insertElementAt(str, targetIndex);
list1.setSelectedIndex(targetIndex);
}else{
model.insertElementAt(str, targetIndex);
model.removeElementAt(draggedIndex);
list1.setSelectedIndex(targetIndex-1);
}
e.dropComplete(true);
}else{
e.dropComplete(false);
}
}catch(UnsupportedFlavorException ex) {
e.dropComplete(false);
}catch(IOException ie) {
e.dropComplete(false);
}
e.dropComplete(false);
targetIndex = -1;
list1.repaint();
}
#spanadd
@Override public void drop(DropTargetDropEvent e) {
#spanend
DefaultListModel model = (DefaultListModel) getModel();
Transferable t = e.getTransferable();
DataFlavor[] f = t.getTransferDataFlavors();
try {
if (isDropAcceptable(e)) {
Component comp = (Component) t.getTransferData(f[0]);
Object str = model.getElementAt(draggedIndex);
if (targetIndex == draggedIndex) {
setSelectedIndex(targetIndex);
} else if (targetIndex < draggedIndex) {
model.removeElementAt(draggedIndex);
model.insertElementAt(str, targetIndex);
setSelectedIndex(targetIndex);
} else {
model.insertElementAt(str, targetIndex);
model.removeElementAt(draggedIndex);
setSelectedIndex(targetIndex - 1);
}
e.dropComplete(true);
} else {
e.dropComplete(false);
}
} catch (UnsupportedFlavorException | IOException ex) {
e.dropComplete(false);
}
e.dropComplete(false);
targetIndex = -1;
repaint();
#spanadd
}
#spanend
#spanadd
View in GitHub: Java, Kotlin- &jnlp;
- &jar;
- &zip;
解説
上記のサンプルでは、ドラッグソースとドラッグターゲットの両方をJList
自身に設定して、項目をドラッグ&ドロップしているように見せかけています。
解説
上記のサンプルでは、ドラッグソースとドラッグターゲットの両方をJList自身に設定して、項目をドラッグ&ドロップしているように見せかけています。- 複数アイテムを選択して移動する場合はTransferHandlerを使ったJListのドラッグ&ドロップによる並べ替えのサンプルなどを参照
参考リンク
- Introduction to Drag and Drop and Data Transfer
- Swing (Archive) - DND from a JList with a single gesture
- Swing (Archive) - Smoother Drag Drop JList JTable
- TransferHandlerを使ったJListのドラッグ&ドロップによる並べ替え
- JListのアイテムをラバーバンドで複数選択、ドラッグ&ドロップで並べ替え
参考リンク
- How to Use Drag and Drop and Data Transfer
- DND from a JList with a single gesture
- Smoother Drag Drop JList JTable
コメント
- 以下を修正しました。 -- aterai
- ドラッグで選択されたアイテムがずれにくいように修正
- ドロップしたあとアイテムが選択状態になるように修正
- アイテムの無い場所にドラッグすると一番最後の項目の下にラインを引くように修正(以前は一番下のアイテムの下半分にドラッグした場合のみ、そこに線を引いていた)
- アイテムを複数選択した状態でドラッグすると
Exception
が発生する不具合を修正しました。 -- aterai - ドラッグ中マウスが
JList
の外に出た場合、カーソルを変更するように変更しました。 -- aterai -
JTabbedPane
にJList
を追加し、タブを二つ作りました。JList
の項目を他のタブへD&D
すると、mouseReleased
メソッドが反応しないのですが、どうすれば回避できますでしょうか。 -- sao-
削除しましたを作ってsrc2.zip
XP
+JDK 1.6.0_02
で試してみたのですが、JList
の項目を他のタブへのD&D
が不可のようです。環境が違うのかな? -- aterai
-
- ぉー!ファイル、わざわざありがとうございます!自分なりに頑張ってます。私がやりたのは
JList
の項目をタブへD&D
して項目に書かれている内容を他のタブ(の持ってるJList
)へ渡したいんです。現状は、2
つ以上の項目なら渡せて、1
つだとエラーがでてしまいます。よくわかっていないまま進めてるので、全然わからないです(汗) -- sao- あ、
src2.zip
は的外れでしたね。このページのDnDList
をJTabbedPane
に入れて、項目をタブタイトルにドロップするとException
の発生するバグがあるのかも?と勘違いしていました。このページのサンプルを改造するなら、src2.zip
ではなく、こちらのソース(名前を変更しました)、チュートリアルならDrag and Drop and Data Transfer: Examples (The Java™ Tutorials > Creating a GUI with Swing > Drag and Drop and Data Transfer)が参考になるかも。 -- aterai
- あ、
-
src3
ありがとうございます☆軽快に動きますね!すごく!src3
ですが、DnDList
にsetEnabled(true);
を追加しました。が、まったくわからず…思いのほか、2
項目以上のD&D
って難しいですネ(汗 -- sao
コメント
- 以下を修正しました。 -- terai
- ドラッグで選択されたアイテムがずれにくいように修正
- ドロップしたあとアイテムが選択状態になるように修正
- アイテムの無い場所にドラッグすると一番最後の項目の下にラインを引くように修正(以前は一番下のアイテムの下半分にドラッグした場合のみ、そこに線を引いていた)
- アイテムを複数選択した状態でドラッグするとExceptionが発生する不具合を修正しました。 -- terai