【问题标题】:Retain relative mouse position while resizing a JPanel in a JScrollPane在 JScrollPane 中调整 JPanel 的大小时保留相对鼠标位置
【发布时间】:2010-09-19 19:27:50
【问题描述】:

我正在调整 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();
    }
}

【问题讨论】:

    标签: java swing resize


    【解决方案1】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-20
      • 2020-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-02
      • 1970-01-01
      相关资源
      最近更新 更多