2012-10-31 17 views
9

मुझे किसी छवि में ज़ूम इन करते समय व्यूपोर्ट की नई स्थिति की गणना करने की आवश्यकता है।JScrollPane - माउस स्थिति से संबंधित ज़ूम

यूआई बनाया गया है इस प्रकार है:

  • ImagePanel छवि खींचता
  • ImagePanelWrapper आसपास imagePanel
  • jScrollPane एक JPanel रैपिंग है ImagePanelWrapper

जब में या ज़ूम शामिल बाहर, ImagePanel का ज़ूम कारक बदल दिया गया है और ImagePanel का पसंदीदा आकार पुन: गणना किया जा रहा है। इसलिए इस पैनल पर छवि चलता है, भले ही ImagePanel उसी व्यूपोर्ट बिंदु पर रहता है।

उपयोगकर्ता को CTRL को दबाकर और माउस व्हील का उपयोग करने पर निम्न विधियों को बुलाया जाता है। दिए गए बिंदु माउसहेल लिस्टनर द्वारा प्रदान किया गया कर्सर स्थान है। इन विधियों में कार्यक्षमता के साथ छवि ज़ूम इन या आउट होने पर पहले से ही उसी शीर्ष-बाएं-स्थिति पर रह रही है।

समस्या यह है कि मैं सिर्फ माउस के सापेक्ष स्थानांतरित करने के बारे में नहीं समझ सकता, उदाहरण के लिए Paint.NET। कोई विचार?

/** 
* 
*/ 
public void zoomOut(Point point) { 
    this.imagePanel.setZoom(this.imagePanel.getZoom() * 0.9f); 
    Point pos = this.getViewport().getViewPosition(); 

    int newX = (int) (pos.x * 0.9f); 
    int newY = (int) (pos.y * 0.9f); 
    this.getViewport().setViewPosition(new Point(newX, newY)); 

    this.imagePanel.revalidate(); 
    this.imagePanel.repaint(); 
} 

/** 
* 
*/ 
public void zoomIn(Point point) { 
    this.imagePanel.setZoom(this.imagePanel.getZoom() * 1.1f); 
    Point pos = this.getViewport().getViewPosition(); 

    int newX = (int) (pos.x * 1.1f); 
    int newY = (int) (pos.y * 1.1f); 
    this.getViewport().setViewPosition(new Point(newX, newY)); 

    this.imagePanel.revalidate(); 
    this.imagePanel.repaint(); 
} 

उत्तर

34

इन मान्यताओं सही हैं तो:

  • आपूर्ति प्वाइंट व्यूपोर्ट के ऊपरी-बाएं कोने के सापेक्ष है।
  • व्यूपोर्ट के आयाम अंतर्निहित ImagePanel से छोटे हैं। ताकि कर्सर से पहले और ज़ूम ऑपरेशन के बाद छवि में एक ही बिंदु खत्म हो गया है

तो व्यूपोर्ट समायोजित किया जा सकता है, अगर निम्न तरीके से ले जाया गया:

/** 
* 
*/ 
public void zoomOut(Point point) { 
    this.imagePanel.setZoom(this.imagePanel.getZoom() * 0.9f); 
    Point pos = this.getViewport().getViewPosition(); 

    int newX = (int)(point.x*(0.9f - 1f) + 0.9f*pos.x); 
    int newY = (int)(point.y*(0.9f - 1f) + 0.9f*pos.y); 
    this.getViewport().setViewPosition(new Point(newX, newY)); 

    this.imagePanel.revalidate(); 
    this.imagePanel.repaint(); 
} 

/** 
* 
*/ 
public void zoomIn(Point point) { 
    this.imagePanel.setZoom(this.imagePanel.getZoom() * 1.1f); 
    Point pos = this.getViewport().getViewPosition(); 

    int newX = (int)(point.x*(1.1f - 1f) + 1.1f*pos.x); 
    int newY = (int)(point.y*(1.1f - 1f) + 1.1f*pos.y); 
    this.getViewport().setViewPosition(new Point(newX, newY)); 

    this.imagePanel.revalidate(); 
    this.imagePanel.repaint(); 
} 

यहाँ संपूर्णता के लिए गणना करने का तरीका 'खातिर:

enter image description here

+1

+1 बहुत बढ़िया, उत्तर। मैंने थोड़ी देर में देखा है। – max

+0

आप सर एक बड़े धन्यवाद के लायक हैं :) – EyeSpy

+0

मेरे पास एक समान सवाल है। मैं एक ही काम करने के लिए AffineTransform का उपयोग करने की कोशिश कर रहा हूं, और मुझे इस प्रश्न से गणित को लागू करने में कुछ परेशानी हो रही है। यदि आपको समय लगता है, तो क्या आप मेरी मदद कर सकते हैं? http://stackoverflow.com/questions/37509908/zoom-in-at-mouse-cursor – bigblind

2

आप point.x और point.y का उपयोग कर माउस सूचक के स्थान प्राप्त करने में सक्षम होना चाहिए - Point प्रलेखन here को देखें। MouseMotionEvent दस्तावेज़ीकरण here, point.x और point.y पर जोर से माउस के नीचे घटक (JScrollPane) के सापेक्ष हैं।

आप इन मानों को अपनी गणना में शामिल कर सकते हैं। क्या आप इस तरह की तलाश कर रहे थे?

संबंधित मुद्दे