Swing/TableScrollOnTouchScreen の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/TableScrollOnTouchScreen へ行く。
- Swing/TableScrollOnTouchScreen の差分を削除
--- category: swing folder: TableScrollOnTouchScreen title: JTableのドラッグスクロールをタッチスクリーンで実行する tags: [JTable, JScrollPane, MouseMotionListener, Timer, ListSelectionListener] author: aterai pubdate: 2019-07-15T19:32:33.964+09:00 description: JTableのドラッグスクロールをタッチスクリーンで実行可能にするためのリスナーを作成します。 image: https://drive.google.com/uc?id=1pV73QkefF37JYOx942N2Vr8Yq7FsoJHb --- * Summary [#summary] `JTable`のドラッグスクロールをタッチスクリーンで実行可能にするためのリスナーを作成します。 #download(https://drive.google.com/uc?id=1pV73QkefF37JYOx942N2Vr8Yq7FsoJHb) * Source Code Examples [#sourcecode] #code(link){{ class TableTouchScreenHandler extends MouseAdapter implements ListSelectionListener { public static final int VELOCITY = 5; public static final int DELAY = 10; public static final double GRAVITY = .95; private final Cursor dc = Cursor.getDefaultCursor(); private final Cursor hc = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); private final Timer scroller; private final Point startPt = new Point(); private final Point delta = new Point(); protected TableTouchScreenHandler(JTable table) { super(); this.scroller = new Timer(DELAY, e -> { System.out.print("."); JViewport vport = (JViewport) SwingUtilities.getUnwrappedParent(table); Point vp = vport.getViewPosition(); vp.translate(-delta.x, -delta.y); table.scrollRectToVisible(new Rectangle(vp, vport.getSize())); if (Math.abs(delta.x) > 0 || Math.abs(delta.y) > 0) { delta.setLocation((int) (delta.x * GRAVITY), (int) (delta.y * GRAVITY)); } else { ((Timer) e.getSource()).stop(); } }); } @Override public void mousePressed(MouseEvent e) { System.out.println("mousePressed: " + delta); Component c = e.getComponent(); c.setCursor(hc); // c.setEnabled(false); Container p = SwingUtilities.getUnwrappedParent(c); if (p instanceof JViewport) { startPt.setLocation(SwingUtilities.convertPoint(c, e.getPoint(), p)); scroller.stop(); } } @Override public void mouseDragged(MouseEvent e) { Component c = e.getComponent(); Container p = SwingUtilities.getUnwrappedParent(c); if (p instanceof JViewport) { JViewport vport = (JViewport) p; Point cp = SwingUtilities.convertPoint(c, e.getPoint(), vport); Point vp = vport.getViewPosition(); vp.translate(startPt.x - cp.x, startPt.y - cp.y); delta.setLocation(VELOCITY * (cp.x - startPt.x), VELOCITY * (cp.y - startPt.y)); ((JComponent) c).scrollRectToVisible(new Rectangle(vp, vport.getSize())); startPt.setLocation(cp); } } @Override public void mouseReleased(MouseEvent e) { System.out.println("mouseReleased: " + delta); JTable c = (JTable) e.getComponent(); c.setCursor(dc); // c.setEnabled(true); if (c.isEditing()) { delta.setLocation(0, 0); } else { scroller.start(); } } @Override public void valueChanged(ListSelectionEvent e) { System.out.println("\nvalueChanged: " + e.getValueIsAdjusting()); if (scroller.isRunning()) { System.out.println("isRunning"); delta.setLocation(0, 0); } scroller.stop(); } } }} * Explanation [#explanation] 上記のサンプルでは、ドラッグによるスクロールは[[JTableをスクロールバー無しのドラッグでスクロールする>Swing/HandDragScrollableTable]]と同じマウスリスナーを使用していますが、タッチスクリーン上で実行するために以下の変更を追加しています。 - タッチした時点ではそのタッチイベントが取得できない?ため、`ListSelectionListener`を追加して行が選択されたらスクロールを中断する - タッチがドラッグではなくセル編集開始の場合はスクロール開始を実行しない -- 編集終了のタッチの場合でもスクロールが開始されないようにするため、編集開始時点で移動量を`0`に設定する必要がある -- この設定をしない場合、例えば`0`列`0`行目のセルを編集状態にしたあと`2`列`10`行目のチェックボックスをタッチすると自動スクロールが開始されてしまう * Reference [#reference] - [[JTableをスクロールバー無しのドラッグでスクロールする>Swing/HandDragScrollableTable]] -- こちらのサンプルではタッチスクリーンを指で操作した場合、セル編集やスクロールの停止に不具合がある * コメント [#comment] * Comment [#comment] #comment #comment