Swing/DividerLocationDragLayer の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/DividerLocationDragLayer へ行く。
- Swing/DividerLocationDragLayer の差分を削除
--- category: swing folder: DividerLocationDragLayer title: JSplitPaneに追加したコンポーネントをドラッグしてDividerの位置を変更する tags: [JSplitPane, Divider, JLayer] author: aterai pubdate: 2016-05-30T00:20:49+09:00 description: JSplitPaneに追加した子コンポーネントの余白などをドラッグしてDividerの位置を変更可能にするJLayerを設定します。 image: https://lh3.googleusercontent.com/-XN3zaDJCb4g/V0sFzBq9QTI/AAAAAAAAOYQ/B2Y_715QARo0KbrhzgyG73OaYqKmeZwvgCCo/s800/DividerLocationDragLayer.png --- * 概要 [#summary] `JSplitPane`に追加した子コンポーネントの余白などをドラッグして`Divider`の位置を変更可能にする`JLayer`を設定します。 #download(https://lh3.googleusercontent.com/-XN3zaDJCb4g/V0sFzBq9QTI/AAAAAAAAOYQ/B2Y_715QARo0KbrhzgyG73OaYqKmeZwvgCCo/s800/DividerLocationDragLayer.png) * サンプルコード [#sourcecode] #code(link){{ class DividerLocationDragLayerUI extends LayerUI<JSplitPane> { private int dividerLocation; private final Point startPt = new Point(); @Override public void installUI(JComponent c) { super.installUI(c); if (c instanceof JLayer) { ((JLayer) c).setLayerEventMask( AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK); } } @Override public void uninstallUI(JComponent c) { if (c instanceof JLayer) { ((JLayer) c).setLayerEventMask(0); } super.uninstallUI(c); } @Override protected void processMouseEvent( MouseEvent e, JLayer<? extends JSplitPane> l) { JSplitPane splitPane = l.getView(); Component c = e.getComponent(); if (splitPane.equals(SwingUtilities.getUnwrappedParent(c)) && e.getID() == MouseEvent.MOUSE_PRESSED) { startPt.setLocation(SwingUtilities.convertPoint(c, e.getPoint(), splitPane)); startPt.setLocation( SwingUtilities.convertPoint(c, e.getPoint(), splitPane)); dividerLocation = splitPane.getDividerLocation(); } } @Override protected void processMouseMotionEvent( MouseEvent e, JLayer<? extends JSplitPane> l) { JSplitPane splitPane = l.getView(); Component c = e.getComponent(); if (splitPane.equals(SwingUtilities.getUnwrappedParent(c)) && e.getID() == MouseEvent.MOUSE_DRAGGED) { Point pt = SwingUtilities.convertPoint(c, e.getPoint(), splitPane); int delta = splitPane.getOrientation() == JSplitPane.HORIZONTAL_SPLIT ? pt.x - startPt.x : pt.y - startPt.y; splitPane.setDividerLocation(Math.max(0, dividerLocation + delta)); } } } }} * 解説 [#explanation] 上記のサンプルでは、`JSplitPane`の`Divider`をマウスでドラッグするだけでなく`JSplitPane#setRightComponent(...)`などで追加した子コンポーネントをマウスでドラッグすることで分割位置を変更できるように`JSplitPane`にマウスイベントを取得する`LayerUI`を設定しています。 - ドラッグ可能になるのは`JSplitPane`の子コンポーネントの余白(そのコンポーネントが別途マウスイベントを処理しない領域) -- 例えばマウスリスナーを追加していない`JLabel`はドラッグ可能、`JButton`などはドラッグ不可となる * 参考リンク [#reference] - [https://stackoverflow.com/questions/37462651/jsplitpane-small-border-but-big-grab-hitbox java - JSplitPane small border but big grab-hitbox - Stack Overflow] * コメント [#comment] #comment #comment