2008-10-29 8 views
4

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(); 
    } 
} 

Répondre

2

Essayez de trouver la place la position de la souris en pourcentage de la taille actuelle, l'application alors que la nouvelle taille:

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

comme exemple. De cette façon, vous regardez la position de la souris par rapport au volet de défilement, et en préservant cette relation sur le zoomPanel.

Questions connexes