Bonjour à tous,
Je suis en train de développer une carte zoomable avec le point de la souris qui reste invariant. J'obtient des résultats corrects excepté pour le premier zoom. Mon calcul a été vérifié plusieurs fois et au moment de mettre les valeurs de setViewPosition, elles sont bonnes, mais cette fameuse viewPosition est fixé a 15, 15 dans la suite du programme et je n'arrive pas à trouver ou cela a lieu, car ensuite le zoom marche parfaitement.
Graphiquement cela se traduit par le fait que vue est mauvaise pour le premier zoom et ensuite pour les prochains zooms le point de la souris est bien invariant.
Mon code à été simplifié pour cet exemple
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 public class MainClass { public static void main(String[] args) { Controler controler = new Controler(); View view = new View(controler); controler.setViewWeak(view); } }
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public class View extends JFrame { private final static int WIDTH = 1200; //1200 private final static int HEIGHT = 700; //770 private Controler controler; private ResizableImage imageMap; // inherite from JPanel private JScrollPane scrollPane; // without attribute like private, protected, public : means frendly //private JPanel pane; // this panel contains the JscrollPane public ResizableImage getImageMap() { return imageMap; } public void setImageMap(ResizableImage imageMap) { this.imageMap = imageMap; } public JScrollPane getScrollPane() { return scrollPane; } public void setScrollPane(JScrollPane scrollPane) { this.scrollPane = scrollPane; } public View(Controler controler) { super("Projet"); // Appel a la fonction mere (JFrame) et donc son constructeur qui prend le nom de la fenetre this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // pour pouvoir rendre le bouton de fermeture reactif this.controler = controler; // Permet de centrer la fenetre au milieu de l'ecran Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); this.setBounds( (int) ( dim.getWidth() - WIDTH ) / 2, (int) ( dim.getHeight() - HEIGHT ) / 2, WIDTH, HEIGHT); this.setPreferredSize(new Dimension(WIDTH, HEIGHT)); this.setResizable(false); this.getContentPane().setLayout(new FlowLayout()); this.imageMap = new ResizableImage(new File("./carte.gif")); this.imageMap.addMouseWheelListener(this.controler); this.imageMap.addMouseMotionListener(this.controler); this.imageMap.addMouseListener(this.controler); this.imageMap.setPreferredSize(new Dimension(934,600));//934,654 scrollPane = new JScrollPane(imageMap); this.getContentPane().add(scrollPane); this.pack(); this.setVisible(true); } }
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class Controler implements ActionListener, MouseWheelListener, MouseInputListener { private WeakReference<View> viewWeak; public void setViewWeak(View view) { this.viewWeak = new WeakReference<View>(view); } public WeakReference<View> getViewWeak() { return viewWeak; } public void actionPerformed(ActionEvent e) { } @Override public void mouseWheelMoved(MouseWheelEvent e) { if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL ) { int i = e.getWheelRotation(); if( i > 0 ){ int lX = e.getX(); int lY = e.getY(); System.out.println("on recupere la vue actuelle"); Point VxVy = this.viewWeak.get().getScrollPane().getViewport().getViewPosition(); int x = (int) (lX - VxVy.getX()); int y = (int) (lY - VxVy.getY()); if( this.viewWeak.get().getImageMap().isPossibleToZoomIn(1.1)){ this.viewWeak.get().getImageMap().setZoom(1.1); int lXp = (int) (lX * 1.1); int lYp = (int) (lY * 1.1); int VxP = (int) (x*(1.1 - 1) + 1.1 * VxVy.getX()); int VyP = (int) (y*(1.1 - 1) + 1.1 * VxVy.getY()); //System.out.println("ViewPosition : "+this.viewWeak.get().getScrollPane().getViewport().getViewPosition()); System.out.println("on applique la nouvelle vue"); this.viewWeak.get().getScrollPane().getViewport().setViewPosition(new Point(VxP, VyP)); } } } System.out.println("ViewPosition fin methode : "+this.viewWeak.get().getScrollPane().getViewport().getViewPosition()); } }
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 public class ResizableImage extends JPanel { private BufferedImage image; private final int minWidth = 934; private final int minHeight = 654; private final int maxWidth = 9807; private final int maxHeight = 6867; private double zoomX = maxWidth / minWidth; // zoom of the view considering the size of the picture private double zoomY = maxHeight / minHeight; public double getZoomX() { return zoomX; } public void setZoomX(double zoom){ this.zoomX = zoom; } public double getZoomY() { return zoomY; } public void setZoomY(double zoom){ this.zoomY = zoom; } public ResizableImage(File file){ try { this.image = ImageIO.read(file); } catch (IOException e) { // TODO Auto-generated catch block System.out.println("capture exception"); e.printStackTrace(); } } public void paintComponent(Graphics g){ Graphics2D g2D = (Graphics2D) g; Dimension dim = getPreferredSize(); g2D.drawImage(image, 0, 0, dim.width, dim.height, this); } public boolean isPossibleToZoomOut(double zoom){ int w = (int) (zoom * this.getSize().getWidth()); int h = (int) (zoom * this.getSize().getHeight()); if( zoom >= 1 || w > this.minWidth || h > this.minHeight) return true; else return false; } public boolean isPossibleToZoomIn(double zoom){ int w = (int) (zoom * this.getSize().getWidth()); int h = (int) (zoom * this.getSize().getHeight()); if( w >= this.maxWidth || h >= this.maxHeight){ return false; } else return true; } public void setZoom(double zoom) { if( zoom < 1){ if( this.isPossibleToZoomOut(zoom) ){ int w = (int) (zoom * this.getSize().getWidth()); int h = (int) (zoom * this.getSize().getHeight()); setPreferredSize(new Dimension(w, h)); revalidate(); repaint(); } else{ if( this.getPreferredSize() != new Dimension(this.minWidth, this.minHeight)){ setPreferredSize(new Dimension(this.minWidth, this.minHeight)); revalidate(); repaint(); } } } else{ if( this.isPossibleToZoomIn(zoom) ){ int w = (int) (zoom * this.getSize().getWidth()); int h = (int) (zoom * this.getSize().getHeight()); setPreferredSize(new Dimension(w, h)); revalidate(); repaint(); } } } public int getMinWidth() { return minWidth; } public int getMaxWidth() { return maxWidth; } }
Partager