IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

AWT/Swing Java Discussion :

Centrage souris zoom ScrollPane


Sujet :

AWT/Swing Java

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2012
    Messages : 17
    Par défaut Centrage souris zoom ScrollPane
    Bonsoir,

    Je cherche depuis quelques temps a pouvoir zoomer (avec la molette) et à centrer la vue sur la fleche de la souris pour une carte. Un peu comme sur Google maps

    Pour se faire, j'utilise un JscrollPan. J'arrive uniquement a centrer la map avec ce cope :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    	@Override
    	public void mouseWheelMoved(MouseWheelEvent e) {
     
    		if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
     
    			int i =  e.getWheelRotation();
     
    			if( i > 0 ){
    				this.viewWeak.get().imageMap.setZoom(1.01);
     
    				Rectangle bounds = this.viewWeak.get().scrollPane.getViewport().getViewRect();
    				Dimension size = this.viewWeak.get().scrollPane.getViewport().getViewSize();
    				int x = (size.width - bounds.width) / 2;
    				int y = (size.height - bounds.height) / 2;
     
     
    				this.viewWeak.get().scrollPane.getViewport().setViewPosition(new Point(x, y));
    			}
    			else if(i < 0){
    				this.viewWeak.get().imageMap.setZoom(0.99);
     
    				Rectangle bounds = this.viewWeak.get().scrollPane.getViewport().getViewRect();
    				Dimension size = this.viewWeak.get().scrollPane.getViewport().getViewSize();
    				int x = (size.width - bounds.width) / 2;
    				int y = (size.height - bounds.height) / 2;
     
     
    				this.viewWeak.get().scrollPane.getViewport().setViewPosition(new Point(x, y));
    			}
    		}
     
    	}

    setZoom me permet de repeindre en plus gros ou plus petit.


    Ici je cherche donc à définir x, y pour bouger la vue de façon progressive en fonction de la souris.

    Je peux récupérer les coordonnées de la souris au moment du scroll avec e.getX() et e.getY().


    Est ce que quelqu'un aurait une idée s'il vous plait ?

    Blackbull

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Tu veux centrer le point qui se trouve sur la souris, ou tu veux que ce point soit invariant pendant le zoom? Google map fait le deuxième, si je scrolle sur la tour eiffel en bas à droite, dans google maps, la tour eiffel reste en bas à droite


    Tout ce que je peux te recommander, parce que j'ai pas envie de faire le calcul, c'est de prendre un papier, un crayon et faire le calcul à la main une fois, comme ça tu verra de quoi tout ce calcul dépend. Ton principe étant

    1) identifier quel point de ton image se trouve sous le e.getX() / e.getY(), ca dépendra du scrollpane et du facteur zoom de ton panel
    2) le zoom
    3) calculer la position zoomée de ce x/Y du point 1
    4) en fonction du scrollpane et de ses dimension, calculer comment il doit être en scrollX / scrollY pour que le ce nouveau x/y soit au même en droit à l'écran que le e.getX / e.getY

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2012
    Messages : 17
    Par défaut
    Ok Merci pour ces pistes, le point invariant sous la souris est une tres bonne idee !
    J'avais deja utiliser un papier et un crayon, mais a chaque fois que je code ca j'ai des surprises.

    Bref je refais ca et je vous tient au courant !

    Merci

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2012
    Messages : 17
    Par défaut
    Salut à tous,

    j'ai fait sur papier la demarche mais ca ne marche pas avec Swing, voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    public void mouseWheelMoved(MouseWheelEvent e) {
     
    		if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
     
    			int i =  e.getWheelRotation();
     
     
     
    			if( i > 0 ){
     
     
    				Point pointUnderMouse = new Point(e.getX(),e.getY());
    				System.out.print("Under Mouse : ");
    				System.out.println(pointUnderMouse.toString()+'\n');
     
    				this.viewWeak.get().imageMap.setZoom(1.1);
    				Rectangle bounds = this.viewWeak.get().scrollPane.getViewport().getViewRect();
    				Dimension size = this.viewWeak.get().scrollPane.getViewport().getViewSize();
     
    				double zoomX = size.getWidth() / bounds.getWidth();
    				double zoomY = size.getHeight() / bounds.getHeight();
     
    				Point pointAfterZoom = new Point( (int) (pointUnderMouse.getX()*1.1) , (int) (pointUnderMouse.getY()*1.1) );
    				System.out.print("After zoom : ");
    				System.out.println(pointAfterZoom.toString()+'\n');
     
    				Point upperLeftHandCorner = new Point();
    				upperLeftHandCorner.x = (int) ( (pointAfterZoom.getX() - pointUnderMouse.getX())  );
    				upperLeftHandCorner.y = (int) ( (pointAfterZoom.getY() - pointUnderMouse.getY())  );
    				System.out.print("upper Left : ");
    				System.out.println(upperLeftHandCorner.toString()+'\n');
     
     
    				this.viewWeak.get().scrollPane.getViewport().setViewPosition(upperLeftHandCorner);
     
     
     
    			}
    			else if(i < 0){...
    Des idees ?

  5. #5
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Si ça peut t'aider, voilà les formules que j'applique pour faire un zoom à la molette, avec point fixe, sur un de mes composant.

    Note que le composant, contrairement à ton cas, ne grandit pas, c'est juste la zone affichée qui change. Mais ça ne devrais pas être dur d'extrapoler la méthode qui t'intéresse

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
            public void mouseWheelMoved(MouseWheelEvent e) {
     
    			float scale = 0.0f;
    			if (e.getWheelRotation() < 1)
    				scale = 1.0f - (0.2f * e.getWheelRotation());
    			else
    				scale = 1.0f / (1.0f + (0.2f * e.getWheelRotation()));
    			final int zoomX = e.getX();
    			final int zoomY = e.getY();
     
    			addZoom(scale, zoomX, zoomY);
    		}
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    	public void addZoom(float scale, int zoomX, int zoomY) {
    		// Zoom translate
    		final float newWidth = getWidth() / scale;
    		final float newHeight = getHeight() / scale;
    		final Point2D center = new Point2D.Float(zoomX - (newWidth / 2), zoomY
    				- (newHeight / 2));
    		final AffineTransform at = new AffineTransform();
    		at.scale(scale, scale);
    		at.translate(-zoomX * (1 - (1 / scale)), -zoomY * (1 - (1 / scale)));
    		at.concatenate(getRenderingTransform());
    		setRenderingTransform(at);
     
    		if (log.isDebugEnabled())
    			log.debug(
    					"Point is (%d,%d); size is (%d,%d); new size is (%f,%f), scale is %f; scale center is (%f,%f)\n",
    					zoomX, zoomY, getWidth(), getHeight(), newWidth, newHeight,
    					scale, center.getX(), center.getY());
    		controller.scaleChanged();
    	}

  6. #6
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Avant de zoomer depuis la position de souris, est ce que tu parviens à zoomer depuis le point haut gauche de la vue ?
    Zoomer depuis la position de souris devrait ensuite être une formalité : déplacer la vue pour faire correspondre le haut-gauche avec la souris, zoomer et enfin déplacer la vue pour que le haut-gauche soit au centre de la vue.
    C'est un problème courant de changement de repère, mais se mélanger les pinceaux est vite fait
    Procède par étape, sans coder tout d'un coup. Vérifie à chaque étape si le comportement est celui attendu.

    EDIT : trop lent
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  7. #7
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2012
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2012
    Messages : 17
    Par défaut
    Merci tchize_ pour ton aide, meme si j'ai un un peu de mal avec tes objets et méthodes.
    Mais j'ai l'impression que j'ai un problème de conception. En effet ici je grossi une image et la vu reste à une taille fix, donc à chaque fois que j'utilise la molette il faut repeindre.

    Etait-il possible de dessiner mon image et ensuite de faire varier la taille de ma vue dans le JScrollPane ?



    EDIT :

    dinobogan, oui j'arrive a Zoomer en haut a gauche, il y a pas grand chose a faire, mais ensuite l'histoire du point invariant, j'obtient un comportement étrange

Discussions similaires

  1. déplacement souris zoom
    Par adriennoob dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 15/04/2010, 20h44
  2. Bouger image avec clavier souris + zoom avec molette
    Par yggdrasylv dans le forum Interfaces Graphiques en Java
    Réponses: 4
    Dernier message: 03/03/2009, 00h02
  3. [FLASH MX2004] Zoom au passage de la souris
    Par pierrot10 dans le forum Flash
    Réponses: 1
    Dernier message: 26/01/2006, 10h38
  4. [C#] Problème de centrage de la souris dans un formulaire.
    Par aegypius dans le forum Windows Forms
    Réponses: 2
    Dernier message: 29/10/2004, 11h46
  5. Fonction de zoom à partir d'une sélection souris
    Par mick74 dans le forum OpenGL
    Réponses: 2
    Dernier message: 13/08/2004, 21h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo