Je redimensionne un JPanel à l'intérieur d'un JScrollPane, et je veux m'assurer que le point sur le JPanel où se trouve actuellement ma souris conserve sa position par rapport à la JScrollPane après le redimensionnement (comme Google maps le fait quand vous zoomez/dézoomez).Conserver la position relative de la souris pendant le redimensionnement d'un JPanel dans un JScrollPane
Je trouve la position de la souris sur le JPanel, ce qui me permet de gérer la position de la fenêtre à différentes positions. Je le multiplie par le facteur de zoom, donc je sais où le point sera après la mise à l'échelle. Je soustrais ensuite la position de la souris sur le ScrollPane pour que je sache où était le point par rapport à la zone visible. Je fais quelque chose de mal cependant, et je ne peux tout simplement pas voir quoi.
Exemple de code:
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();
}
}