Swing/RearrangeOrderOfPanels のバックアップソース(No.9)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- バックアップ を表示
- Swing/RearrangeOrderOfPanels へ行く。
- 1 (2015-03-18 (水) 18:50:14)
- 2 (2015-04-05 (日) 23:09:13)
- 3 (2015-05-28 (木) 17:41:23)
- 4 (2015-12-17 (木) 14:37:40)
- 5 (2016-05-16 (月) 11:45:57)
- 6 (2016-05-25 (水) 13:16:39)
- 7 (2017-04-07 (金) 13:51:51)
- 8 (2017-08-04 (金) 15:48:13)
- 9 (2018-08-03 (金) 14:14:36)
- 10 (2019-09-17 (火) 19:14:26)
- 11 (2019-12-26 (木) 23:19:08)
- 12 (2021-06-29 (火) 18:41:13)
--- category: swing folder: RearrangeOrderOfPanels title: JPanelの並び順をドラッグ&ドロップで入れ替える tags: [JPanel, DragAndDrop, MouseListener, MouseMotionListener, JWindow] author: aterai pubdate: 2014-12-08T00:00:10+09:00 description: JPanelに配置した子コンポーネントの並び順を、マウスのドラッグ&ドロップによる入れ替えで変更します。 image: https://lh3.googleusercontent.com/-9IOKBRfVxZE/VIRiCikcIkI/AAAAAAAANss/0DrZLpxPEWo/s800/RearrangeOrderOfPanels.png --- * 概要 [#summary] `JPanel`に配置した子コンポーネントの並び順を、マウスのドラッグ&ドロップによる入れ替えで変更します。 #download(https://lh3.googleusercontent.com/-9IOKBRfVxZE/VIRiCikcIkI/AAAAAAAANss/0DrZLpxPEWo/s800/RearrangeOrderOfPanels.png) * サンプルコード [#sourcecode] #code(link){{ class RearrangingHandler extends MouseAdapter { private static final Rectangle R1 = new Rectangle(); private static final Rectangle R2 = new Rectangle(); private final Rectangle prevRect = new Rectangle(); private final int gestureMotionThreshold = DragSource.getDragThreshold(); private final JWindow window = new JWindow(); private final Point startPt = new Point(); private int index = -1; private Component draggingComonent; private Component gap; private final Point dragOffset = new Point(); public RearrangingHandler() { super(); window.setBackground(new Color(0x0, true)); } @Override public void mousePressed(MouseEvent e) { if (((JComponent) e.getComponent()).getComponentCount() <= 1) { startPt.setLocation(0, 0); } else { startPt.setLocation(e.getPoint()); } } private void startDragging(JComponent parent, Point pt) { Component c = parent.getComponentAt(pt); index = parent.getComponentZOrder(c); if (Objects.equals(c, parent) || index < 0) { return; } draggingComonent = c; Dimension d = draggingComonent.getSize(); Point dp = draggingComonent.getLocation(); dragOffset.setLocation(pt.x - dp.x, pt.y - dp.y); gap = Box.createRigidArea(d); swapComponentLocation(parent, c, gap, index); window.add(draggingComonent); //window.setSize(d); window.pack(); updateWindowLocation(pt, parent); window.setVisible(true); } private void updateWindowLocation(Point pt, JComponent parent) { if (window.isVisible() && Objects.nonNull(draggingComonent)) { Point p = new Point(pt.x - dragOffset.x, pt.y - dragOffset.y); SwingUtilities.convertPointToScreen(p, parent); window.setLocation(p); } } private int getTargetIndex(Rectangle r, Point pt, int i) { int ht2 = (int) (.5 + r.height * .5); R1.setBounds(r.x, r.y, r.width, ht2); R2.setBounds(r.x, r.y + ht2, r.width, ht2); if (R1.contains(pt)) { prevRect.setBounds(R1); return i - 1 > 0 ? i : 0; } else if (R2.contains(pt)) { prevRect.setBounds(R2); return i; } return -1; } private static void swapComponentLocation( Container parent, Component remove, Component add, int idx) { parent.remove(remove); parent.add(add, idx); parent.revalidate(); parent.repaint(); } @Override public void mouseDragged(MouseEvent e) { Point pt = e.getPoint(); JComponent parent = (JComponent) e.getComponent(); if (Objects.isNull(draggingComonent)) { if (startPt.distance(pt) > gestureMotionThreshold) { startDragging(parent, pt); } return; } updateWindowLocation(pt, parent); if (prevRect.contains(pt)) { return; } for (int i = 0; i < parent.getComponentCount(); i++) { Component c = parent.getComponent(i); Rectangle r = c.getBounds(); if (Objects.equals(c, gap) && r.contains(pt)) { return; } int tgt = getTargetIndex(r, pt, i); if (tgt >= 0) { swapComponentLocation(parent, gap, gap, tgt); return; } } //System.out.println("outer"); parent.remove(gap); parent.revalidate(); } @Override public void mouseReleased(MouseEvent e) { startPt.setLocation(0, 0); dragOffset.setLocation(0, 0); prevRect.setBounds(0, 0, 0, 0); window.setVisible(false); Point pt = e.getPoint(); JComponent parent = (JComponent) e.getComponent(); Component cmp = draggingComonent; draggingComonent = null; for (int i = 0; i < parent.getComponentCount(); i++) { Component c = parent.getComponent(i); if (Objects.equals(c, gap)) { swapComponentLocation(parent, gap, cmp, i); return; } int tgt = getTargetIndex(c.getBounds(), pt, i); if (tgt >= 0) { swapComponentLocation(parent, gap, cmp, tgt); return; } } if (parent.getParent().getBounds().contains(pt)) { swapComponentLocation(parent, gap, cmp, parent.getComponentCount()); } else { swapComponentLocation(parent, gap, cmp, index); } } } }} * 解説 [#explanation] 上記のサンプルでは、親の`JPanel`に`MouseListener`と`MouseMotionListener`を継承するハンドラを追加し、子の`JPanel`をマウスドラッグで任意の位置に差し替えることが出来ます。 - 使用しているハンドラは、以下の`2`点を除いて[[JToolBarに配置したアイコンをドラッグして並べ替える>Swing/RearrangeToolBarIcon]]で使用しているものとほぼ同一 -- 水平ではなく垂直方向に入れ替えを行うように変更 -- サイズ(高さ)の異なるパネルの入れ替えに対応 * 参考リンク [#reference] - [[JToolBarに配置したアイコンをドラッグして並べ替える>Swing/RearrangeToolBarIcon]] - [https://stackoverflow.com/questions/27245283/java-drag-and-drop-to-change-the-order-of-panels swing - Java, drag and drop to change the order of panels - Stack Overflow] * コメント [#comment] #comment #comment