4

我正在调整 JScrollPane 内的 JPanel 的大小,并且我想确保我的鼠标当前所在的 JPanel 上的点在调整大小后保持其相对于 JScrollPane 的位置(就像 Google 地图在您放大/出去)。

我在 JPanel 上找到了鼠标位置,这让我可以处理位于不同位置的视口。我将它乘以缩放因子,所以我知道缩放后点的位置。然后我减去鼠标在 ScrollPane 上的位置,以便我知道该点相对于可视区域的位置。然而,我做错了什么,我只是看不到什么。

示例代码:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;


public class Test 
{
    public static void main(String[] in)
    {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Test();
            }
        });
    }

    public Test()
    {
        final JFrame frame = new JFrame();
        final ScalablePanel child = new ScalablePanel();

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        frame.add(child, BorderLayout.CENTER);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

class ScalablePanel
extends JScrollPane
implements MouseWheelListener
{
    final double ZOOM_IN_FACTOR = 1.1;
    final double ZOOM_OUT_FACTOR = 0.9;
    final JPanel zoomPanel = new JPanel();

    public ScalablePanel()
    {
        final javax.swing.JLabel marker = new javax.swing.JLabel("Testing the mouse position on zoom");
        marker.setHorizontalAlignment(javax.swing.JLabel.CENTER);

        zoomPanel.setLayout(new BorderLayout());
        zoomPanel.add(marker,BorderLayout.CENTER);

        getViewport().setView(zoomPanel);
        setPreferredSize(new Dimension(300,300));
        addMouseWheelListener(this);
    }

    public void mouseWheelMoved(final MouseWheelEvent e) 
    {
        if (e.isControlDown())
        {
            if (e.getWheelRotation() < 0)
                zoomIn(e);
            else
                zoomOut(e);
            e.consume();
        }
    }

    public void zoomIn(final MouseWheelEvent e)
    {
        // Get the mouse position with respect to the zoomPanel
        final Point pointOnZoomPanel = SwingUtilities.convertPoint(
                e.getComponent(), e.getPoint(), zoomPanel);

        // Resize panel
        final Dimension currSize = zoomPanel.getSize();
        zoomPanel.setPreferredSize(
                new Dimension(
                        (int)(currSize.width * ZOOM_IN_FACTOR),
                        (int)(currSize.height * ZOOM_IN_FACTOR) ));

        // Find out where our point on the zoom panel is now that we've resized it
        final Point newViewPos = new Point();
        newViewPos.x = (int)(ZOOM_IN_FACTOR * pointOnZoomPanel.x - e.getPoint().x);
        newViewPos.y = (int)(ZOOM_IN_FACTOR * pointOnZoomPanel.y - e.getPoint().y);
        // Move the viewport to the new position to keep the area our mouse was in the same spot
        getViewport().setViewPosition(newViewPos);

        zoomPanel.revalidate();
    }

    public void zoomOut(final MouseWheelEvent e)
    {
        // Get the mouse position with respect to the zoomPanel
        final Point pointOnZoomPanel = SwingUtilities.convertPoint(
                e.getComponent(), e.getPoint(), zoomPanel);

        // Resize panel
        final Dimension currSize = zoomPanel.getSize();
        zoomPanel.setPreferredSize(
                new Dimension(
                        (int)(currSize.width * ZOOM_OUT_FACTOR),
                        (int)(currSize.height * ZOOM_OUT_FACTOR) ));

        // Find out where our point on the zoom panel is now that we've resized it
        final Point newViewPos = new Point();
        newViewPos.x = (int)(ZOOM_OUT_FACTOR * pointOnZoomPanel.x - e.getPoint().x);
        newViewPos.y = (int)(ZOOM_OUT_FACTOR * pointOnZoomPanel.y - e.getPoint().y);
        // Move the viewport to the new position to keep the area our mouse was in the same spot
        getViewport().setViewPosition(newViewPos);

        zoomPanel.revalidate();
    }
}
4

1 回答 1

2

尝试将鼠标的位置作为当前大小的百分比来查找,然后将其应用于新大小:

newViewPos.x = (int)((ZOOM_IN_FACTOR * currSize.width) * (e.getPoint().x/(double)currSize.width));

举个例子。通过这种方式,您正在查看相对于滚动窗格的鼠标位置,并在 zoomPanel 上保留该关系。

于 2008-10-29T17:57:39.133 回答