JScrollPane内にある複数Componentを配置したJPanelをJLayerを使ってドラッグスクロール
Total: 8229
, Today: 3
, Yesterday: 3
Posted by aterai at
Last-modified:
概要
複数のネストしたComponent
を配置したJPanel
のドラッグイベントを、JScrollPane
をラップしたJLayer
で受け取ってスクロール可能にします。
Screenshot
Advertisement
サンプルコード
class DragScrollLayerUI extends LayerUI<JScrollPane> {
private final Point pp = 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 JScrollPane> l) {
Component c = e.getComponent();
if (c instanceof JScrollBar || c instanceof JSlider) {
return;
}
if (e.getID() == MouseEvent.MOUSE_PRESSED) {
JViewport vport = l.getView().getViewport();
Point cp = SwingUtilities.convertPoint(c, e.getPoint(), vport);
pp.setLocation(cp);
}
}
@Override protected void processMouseMotionEvent(
MouseEvent e, JLayer<? extends JScrollPane> l) {
Component c = e.getComponent();
if (c instanceof JScrollBar || c instanceof JSlider) {
return;
}
if (e.getID() == MouseEvent.MOUSE_DRAGGED) {
JViewport vport = l.getView().getViewport();
JComponent cmp = (JComponent) vport.getView();
Point cp = SwingUtilities.convertPoint(c, e.getPoint(), vport);
Point vp = vport.getViewPosition();
vp.translate(pp.x - cp.x, pp.y - cp.y);
cmp.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
pp.setLocation(cp);
}
}
}
View in GitHub: Java, Kotlin解説
DragScrollListener
- JTreeの余白をドラッグしてスクロール
- このリスナーを追加した一つの
Component
をドラッグしてスクロールが可能 JPanel
を掴んでのスクロールが実行可能だが、その子コンポーネントのJTabbedPane
などをドラッグしてもスクロールは不可
DragScrollLayer
- すべての下位コンポーネントの
MouseEvent
をキャッチするようJLayer#setLayerEventMask(...)
と設定したJLayer
を作成 - この
JLayer
でJScrollPane
をラップし、子にマウスイベントを消費するコンポーネントが存在する場合でも、ビューのJPanel
をドラッグに応じてスクロール JScrollBar
やJSlider
のようにノブのドラッグを使用するコンポーネントは二重にスクロールしてしまうので除外
- すべての下位コンポーネントの
参考リンク
- Java Swing Tips: Mouse Dragging ViewPort Scroll
- JTreeの余白をドラッグしてスクロール
- JScrollPaneのViewportをマウスで掴んでスクロール