0

http://java-swing-tips.blogspot.co.uk/2008/06/mouse-drag-auto-scrolling.htmlをプログラムに統合しようとしましたが、誤動作しているようで、よくわかりません。何が起こっていますか。

gameGridラベルは、実際にはクリックイベントを持つ別個のクラスです。そのため、マウスリスナーが親のmouseListenersを呼び出そうとしています(以前はグリッドmouseListenersがスクロール可能なビューポートmouseListenersをオーバーライドしていたため、ドラッグされませんでした)が、JPanelは一部の形状は同じ動作を示します。

package uk.co.mhayward.games.factions;

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.HeadlessException;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JViewport;

public class WhyYouJump extends JFrame {

    public static void main(String[] args) {
        new WhyYouJump();
    }

    private static final long serialVersionUID = 3697837493691218641L;

    private final JPanel gameGridPanel;

    private final JScrollPane gridScrollPane;

    private final JViewport gridScrollPaneViewport;

    private final JTextArea jTextArea = new JTextArea();

    public WhyYouJump() throws HeadlessException {
        super();

        gameGridPanel = new JPanel() {
            @Override
            public void paint(Graphics g) {
                super.paint(g);
                Graphics2D g2d = (Graphics2D) g;

                Polygon shape1 = new Polygon();
                Polygon shape2 = new Polygon();
                Polygon shape3 = new Polygon();

                for (int i = 0; i < 6; i++) {
                    shape1.addPoint((int) (200 + 50 * Math.cos(i * 2 * Math.PI / 6)),
                            (int) (200 + 50 * Math.sin(i * 2 * Math.PI / 6)));
                    shape2.addPoint((int) (400 + 50 * Math.cos(i * 2 * Math.PI / 6)),
                            (int) (200 + 50 * Math.sin(i * 2 * Math.PI / 6)));
                    shape3.addPoint((int) (100 + 50 * Math.cos(i * 2 * Math.PI / 6)),
                            (int) (100 + 50 * Math.sin(i * 2 * Math.PI / 6)));
                }

                g2d.setStroke(new BasicStroke(3));
                g2d.setPaint(Color.WHITE);
                g2d.fill(shape1);
                g2d.fill(shape2);
                g2d.fill(shape3);
                g2d.setPaint(Color.BLACK);
                g2d.draw(shape1);
                g2d.draw(shape2);
                g2d.draw(shape3);
            }
        };

        gameGridPanel.setPreferredSize(new Dimension(1440, 900));
        gameGridPanel.setSize(new Dimension(1440, 900));

        gridScrollPane = new JScrollPane(gameGridPanel);

        gameGridPanel.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                for (MouseListener l : gameGridPanel.getParent().getMouseListeners()) {
                    e.setSource(gridScrollPaneViewport);
                    l.mousePressed(e);
                }
                jTextArea.append(e.getPoint().toString() + "\n");
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                for (MouseListener l : gameGridPanel.getParent().getMouseListeners()) {
                    e.setSource(gridScrollPaneViewport);
                    l.mouseReleased(e);
                }
            }

            @Override
            public void mouseExited(MouseEvent e) {
                for (MouseListener l : gameGridPanel.getParent().getMouseListeners()) {
                    e.setSource(gridScrollPaneViewport);
                    l.mouseExited(e);
                }
            }
        });

        gameGridPanel.addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                for (MouseMotionListener l : gameGridPanel.getParent().getMouseMotionListeners()) {
                    e.setSource(gridScrollPaneViewport);
                    l.mouseDragged(e);
                }
            }
        });

        gameGridPanel.addHierarchyListener(new HierarchyListener() {

            public void hierarchyChanged(HierarchyEvent e) {
                for (HierarchyListener l : gameGridPanel.getParent().getHierarchyListeners()) {
                    e.setSource(gridScrollPaneViewport);
                    l.hierarchyChanged(e);
                }
            }
        });

        this.setLayout(new BorderLayout());
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        gridScrollPane.setPreferredSize(new Dimension(500, 300));
        gridScrollPane.getVerticalScrollBar().setUnitIncrement(16);

        ViewportDragScrollListener l = new ViewportDragScrollListener(gameGridPanel, false);
        gridScrollPaneViewport = gridScrollPane.getViewport();
        gridScrollPaneViewport.addMouseMotionListener(l);
        gridScrollPaneViewport.addMouseListener(l);
        gridScrollPaneViewport.addHierarchyListener(l);

        this.add("Center", gridScrollPane);

        JScrollPane textScrollPane = new JScrollPane(jTextArea);
        textScrollPane.setPreferredSize(new Dimension(140, 180));
        this.add("South", textScrollPane);

        this.pack();
        this.setLocation(100, 100);
        this.setVisible(true);
    }

    class ViewportDragScrollListener extends MouseAdapter implements HierarchyListener {
        private static final int SPEED = 4;
        private static final int DELAY = 10;
        private final Cursor dc;
        private final Cursor hc = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
        private final javax.swing.Timer scroller;
        private final JComponent label;
        private final Point startPt = new Point();
        private final Point move = new Point();
        private boolean autoScroll = false;

        public ViewportDragScrollListener(JComponent comp, boolean autoScroll) {
            this.label = comp;
            this.autoScroll = autoScroll;
            this.dc = comp.getCursor();
            this.scroller = new javax.swing.Timer(DELAY, new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    JViewport vport = (JViewport) label.getParent();
                    Point vp = vport.getViewPosition();
                    vp.translate(move.x, move.y);
                    label.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
                }
            });
        }

        public void hierarchyChanged(HierarchyEvent e) {
            JComponent c = (JComponent) e.getSource();
            if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0 && !c.isDisplayable() && autoScroll) {
                scroller.stop();
            }
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            JViewport vport = (JViewport) e.getSource();
            Point pt = e.getPoint();
            int dx = startPt.x - pt.x;
            int dy = startPt.y - pt.y;
            Point vp = vport.getViewPosition();
            vp.translate(dx, dy);
            label.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
            move.setLocation(SPEED * dx, SPEED * dy);
            startPt.setLocation(pt);
        }

        @Override
        public void mousePressed(MouseEvent e) {
            ((JComponent) e.getSource()).setCursor(hc); //label.setCursor(hc);
            startPt.setLocation(e.getPoint());
            move.setLocation(0, 0);
            if (autoScroll) {
                scroller.stop();
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            ((JComponent) e.getSource()).setCursor(dc); //label.setCursor(dc);
            if (autoScroll) {
                scroller.start();
            }
        }

        @Override
        public void mouseExited(MouseEvent e) {
            ((JComponent) e.getSource()).setCursor(dc); //label.setCursor(dc);
            move.setLocation(0, 0);
            if (autoScroll) {
                scroller.stop();
            }
        }
    }
}
4

2 に答える 2

2

1つの方法、SwingUtilities.convertMouseEvent(gamePanel、mouseEvent、viewport)を使用する:(編集:Guillaume Poletがすでに言っているように)

MouseAdapter convertMouseEventListener = new MouseAdapter() {
  private void dispatchEvent(MouseEvent e) {
    JComponent c = (JComponent)e.getComponent();
    JComponent p = (JComponent)e.getComponent().getParent();
    p.dispatchEvent(SwingUtilities.convertMouseEvent(c,e,p));
  }
  @Override public void mouseDragged(MouseEvent e)  { dispatchEvent(e); }
  @Override public void mouseClicked(MouseEvent e)  { dispatchEvent(e); }
  @Override public void mouseEntered(MouseEvent e)  { dispatchEvent(e); }
  @Override public void mouseExited(MouseEvent e)   { dispatchEvent(e); }
  @Override public void mousePressed(MouseEvent e)  {
    jTextArea.append(e.getPoint().toString() + "\n");
    dispatchEvent(e);
  }
  @Override public void mouseReleased(MouseEvent e) { dispatchEvent(e); }
};
gameGridPanel.addMouseMotionListener(convertMouseEventListener);
gameGridPanel.addMouseListener(convertMouseEventListener);

もう1つ、gameGridPanelに独自のMouseListenersがある場合、ViewportDragScrollListenerの代わりにComponentDragScrollListenerを使用することをお勧めします。

ComponentDragScrollListener l = new ComponentDragScrollListener(gameGridPanel);
gameGridPanel.addMouseMotionListener(l);
gameGridPanel.addMouseListener(l);
gameGridPanel.addHierarchyListener(l);
于 2012-05-30T11:09:41.647 に答える
2

これが正確に何をしているのかはわかりませんが、少なくとも1つはわかります。イベントを転送しないため、クラスで呼び出されることはmousePressed mouseReleasedありません。記事を見た後、彼らはそのようなテクニックを使用しておらず、これもあなたの問題の一部かもしれないと思います。mouseExitedViewportDragScrollListener

あなたのようにイベントを転送するのではなく、正しいコンポーネントに直接マウスリスナーを追加することを検討してください。

編集:

イベントを転送するときは、ソースを変更しますが、ポイントは元のコンポーネント座標のままです。代わりに、次のコードを使用して新しいイベントを作成することを検討してください。

e = SwingUtilities.convertMouseEvent((Component) e.getSource(), e, gridScrollPaneViewport);
于 2012-05-30T09:51:58.443 に答える