通过拖动鼠标滚动JScrollPane(Java swing) [英] Scroll JScrollPane by dragging mouse (Java swing)

查看:329
本文介绍了通过拖动鼠标滚动JScrollPane(Java swing)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我正在制作的游戏制作地图编辑器。 JScrollPane中有一个JPanel,用于显示要编辑的地图。我想要做的是,当用户按住空格键并在JPanel中拖动鼠标时,JScrollPanel将随拖动一起滚动。以下是我到目前为止:

I am making a map editor for a game I am working on. There is a JPanel in the JScrollPane that displays the map to be edited. What I would like to do is make it that when the user is holding down the Spacebar and dragging their mouse in the JPanel, the JScrollPanel will scroll along with the dragging. Here is what I have so far:

panelMapPanel.addMouseMotionListener(new MouseMotionListener(){

        @Override
        public void mouseDragged(MouseEvent e) {
            //Gets difference in distance x and y from last time this listener was called
            int deltaX = mouseX - e.getX();
            int deltaY = mouseY - e.getY();
            mouseX = e.getX();
            mouseY = e.getY();
            if(spacePressed){
                //Scroll the scrollpane according to the distance travelled
                scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getValue() + deltaY);
                scrollPane.getHorizontalScrollBar().setValue(scrollPane.getHorizontalScrollBar().getValue() + deltaX);
            }
        }

});

目前它可以工作但滚动并不顺畅。一次移动鼠标很好但是做小拖动会使滚动条变得狂暴。

Currently it works but the scrolling is not smooth at all. Moving the mouse a lot at a time is fine but doing small drags makes the scrollpane go berserk.

任何想法如何改善这个?

Any ideas how to improve this?

对于那些喜欢视觉帮助的人,这里是编辑:

For those who enjoy a visual to help, here is the editor:

加法笔记(编辑):


  • 我试过 scrollPane.getViewport()。setViewPosition(new Point(scrollPane.getViewport()。getViewPosition()。x + deltaX,scrollPane.getViewport()。getViewPosition()。y + deltaY));

  • 当慢慢移动鼠标时拖动更加烦躁,而大动作则更加流畅

  • 我尝试使用scrollRectToVisible而没有运气

推荐答案

好的,最终我变得更加简单了,尽管它会... ...

Okay, that ended up been much simpler then I though it would be...

首先,不要弄乱 JViewport ,而是使用 JComponent#scrollRectToVisible 直接在作为 JScrollPane ,应该附加 MouseListener

First, don't mess with the JViewport, instead, use JComponent#scrollRectToVisible directly on the component which is acting as the contents of the JScrollPane, onto which the MouseListener should be attached.

以下示例只是计算点之间的差异用户点击的位置和拖动的金额。然后它将此delta应用于 JViewport viewRect 并使用 JComponent#scrollRectToVisible 更新可查看区域,简单:)

The following example simply calculates the difference between the point at which the user clicked and the amount they have dragged. It then applies this delta to the JViewport's viewRect and uses JComponent#scrollRectToVisible to update the viewable area, simple :)

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JLabel map;

        public TestPane() {
            setLayout(new BorderLayout());
            try {
                map = new JLabel(new ImageIcon(ImageIO.read(new File("c:/treasuremap.jpg"))));
                map.setAutoscrolls(true);
                add(new JScrollPane(map));

                MouseAdapter ma = new MouseAdapter() {

                    private Point origin;

                    @Override
                    public void mousePressed(MouseEvent e) {
                        origin = new Point(e.getPoint());
                    }

                    @Override
                    public void mouseReleased(MouseEvent e) {
                    }

                    @Override
                    public void mouseDragged(MouseEvent e) {
                        if (origin != null) {
                            JViewport viewPort = (JViewport) SwingUtilities.getAncestorOfClass(JViewport.class, map);
                            if (viewPort != null) {
                                int deltaX = origin.x - e.getX();
                                int deltaY = origin.y - e.getY();

                                Rectangle view = viewPort.getViewRect();
                                view.x += deltaX;
                                view.y += deltaY;

                                map.scrollRectToVisible(view);
                            }
                        }
                    }

                };

                map.addMouseListener(ma);
                map.addMouseMotionListener(ma);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

}

这篇关于通过拖动鼠标滚动JScrollPane(Java swing)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆