J'essaye d'implémenter le zoom sensible à la position à l'intérieur d'un JScrollPane
. Le JScrollPane
contient un composant avec un paint
personnalisé qui va se dessiner à l'intérieur de l'espace qui lui est alloué - donc le zoom est aussi simple que d'utiliser un MouseWheelListener
qui redimensionne le composant interne comme requis. Mais je veux aussi zoomer sur (ou sur) un point pour garder ce point aussi central que possible dans la vue agrandie (ou -out) qui en résulte (c'est ce que j'appelle "position-sensitive" zooming), similaire à la façon dont le zoom fonctionne dans google maps. Je suis sûr que cela a été fait à plusieurs reprises auparavant - quelqu'un sait-il la "bonne" façon de le faire sous Java Swing ?. Serait-il préférable de jouer avec les transformations de Graphic2D
au lieu d'utiliser JScrollPanes
?Comment implémenter un zoom sensible à la position dans un JScrollPane?
Exemple de code suivant:
package test;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
public class FPanel extends javax.swing.JPanel {
private Dimension preferredSize = new Dimension(400, 400);
private Rectangle2D[] rects = new Rectangle2D[50];
public static void main(String[] args) {
JFrame jf = new JFrame("test");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setSize(400, 400);
jf.add(new JScrollPane(new FPanel()));
jf.setVisible(true);
}
public FPanel() {
// generate rectangles with pseudo-random coords
for (int i=0; i<rects.length; i++) {
rects[i] = new Rectangle2D.Double(
Math.random()*.8, Math.random()*.8,
Math.random()*.2, Math.random()*.2);
}
// mouse listener to detect scrollwheel events
addMouseWheelListener(new MouseWheelListener() {
public void mouseWheelMoved(MouseWheelEvent e) {
updatePreferredSize(e.getWheelRotation(), e.getPoint());
}
});
}
private void updatePreferredSize(int n, Point p) {
double d = (double) n * 1.08;
d = (n > 0) ? 1/d : -d;
int w = (int) (getWidth() * d);
int h = (int) (getHeight() * d);
preferredSize.setSize(w, h);
getParent().doLayout();
// Question: how do I keep 'p' centered in the resulting view?
}
public Dimension getPreferredSize() {
return preferredSize;
}
private Rectangle2D r = new Rectangle2D.Float();
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.red);
int w = getWidth();
int h = getHeight();
for (Rectangle2D rect : rects) {
r.setRect(rect.getX() * w, rect.getY() * h,
rect.getWidth() * w, rect.getHeight() * h);
((Graphics2D)g).draw(r);
}
}
}
prime Ajouté à voir si je peux obtenir une réponse complète (idéalement: l'extrait de code qui, lorsqu'il est ajouté ci-dessus, répond à la question). – tucuxi