दिलचस्प पोस्ट
क्या मुझे डीटीओ ऑब्जेक्ट्स में एंटिटी (पर्सिस्टेंट) ऑब्जेक्ट्स को बदलना चाहिए? कैसे एक समारोह के लिए एक तर्क के रूप में सरणी को पारित करने के लिए bash कैसे अपाचे mod_rewrite डिबग करने के लिए पायथन में पाइप वर्ण नोहुप और एम्परसेंड में क्या अंतर है IEnumerable <struct> को IEnumerable <object> के रूप में क्यों नहीं डाला जा सकता? एक JSONException प्राप्त करना: इनपुट के अंत में वर्ण 0 कैसे वेब एपीआई के लिए XML प्रलेखन मुख्य परियोजना से परे दस्तावेज शामिल कर सकते हैं? सामग्री पर कर्सर स्थिति सेट करें संपादन <div> अजगर मेरे डिक्शनरी को इतना पसंद क्यों कर रहा है? निमंत्रण या BeginInvoke को एक नियंत्रण पर नहीं बुलाया जा सकता जब तक विंडो हैंडल नहीं बनाया गया हो एक LINQ क्वेरी में SQL उपयोगकर्ता-परिभाषित फ़ंक्शन कॉल करना वेरिएबल और फ़ंक्शन के नामों के लिए पायथन में नेमिंग सम्मेलन क्या है? रिपॉजिटरी में वसूली फ़ाइलों को कैसे ठीक करता है? क्या JQGrid मुक्त है?

JavaFX सही स्केलिंग

मैं स्क्रॉल ईवेंट पर एक फलक में सभी नोड्स को स्केल करना चाहता हूं

मैंने अब तक क्या प्रयास किया है:

  1. जब मैं scaleX या scaleY करता हूँ, तो फलक स्केल की सीमा क्रमशः (जब सेट फलक शैली -fx-border-color: black; )। इसलिए यदि हर बार मैं फलक की सीमाओं से नहीं हूं, तो हर घटना शुरू हो जाएगी, इसलिए मुझे इसकी ज़रूरत है यहां छवि विवरण दर्ज करें

  2. अगले चरण में मैंने प्रत्येक नोड को मापने की कोशिश की और यह वास्तव में खराब हो गया, ऐसा कुछ – (बिंदुओं के माध्यम से लाइनें फैली) या अगर दूसरी तरफ स्क्रॉल करना, तो यह कम होगा यहां छवि विवरण दर्ज करें

  3. एक अन्य विधि मैंने कोशिश की थी नोड के पैमाने को मापने के लिए। यह बेहतर है, लेकिन मुझे यह पसंद नहीं है। यह point.setScaleX(point.getScaleX()+scaleX) की तरह लग रहा है और y और अन्य नोड्स के लिए उपयुक्त है।

Solutions Collecting From Web of "JavaFX सही स्केलिंग"

मैंने स्क्रॉल इवेंट पर एक व्यूपोर्ट में एक नोड के स्केलिंग के प्रदर्शन के लिए एक दृष्टिकोण प्रदर्शित करने के लिए एक नमूना ऐप बनाया है (जैसे माउस व्हील रोल करके स्क्रॉल और बाहर)

एक स्टैकपैन में एक समूह को स्केल करने के लिए नमूने के मुख्य तर्क:

 final double SCALE_DELTA = 1.1; final StackPane zoomPane = new StackPane(); zoomPane.getChildren().add(group); zoomPane.setOnScroll(new EventHandler<ScrollEvent>() { @Override public void handle(ScrollEvent event) { event.consume(); if (event.getDeltaY() == 0) { return; } double scaleFactor = (event.getDeltaY() > 0) ? SCALE_DELTA : 1/SCALE_DELTA; group.setScaleX(group.getScaleX() * scaleFactor); group.setScaleY(group.getScaleY() * scaleFactor); } }); 

स्क्रॉल इवेंट हेन्डलर को संलग्न स्टैकपैन पर सेट किया गया है जो एक resizable फलक है ताकि यह फलक में केंद्रित ज़ूम की गई सामग्री को रखने के लिए किसी भी खाली जगह को भरने के लिए फैलता है। अगर आप स्टैकपैन के अंदर कहीं भी माउस व्हील ले जाते हैं तो यह नोड्स के संलग्न समूह को ज़ूम इन या बाहर कर देगा।

zoomyzoomyin

 import javafx.application.Application; import javafx.beans.value.*; import javafx.event.*; import javafx.geometry.Bounds; import javafx.scene.*; import javafx.scene.control.*; import javafx.scene.image.*; import javafx.scene.input.*; import javafx.scene.layout.*; import javafx.scene.paint.Color; import javafx.scene.shape.*; import javafx.stage.Stage; public class GraphicsScalingApp extends Application { public static void main(String[] args) { launch(args); } @Override public void start(final Stage stage) { final Group group = new Group( createStar(), createCurve() ); Parent zoomPane = createZoomPane(group); VBox layout = new VBox(); layout.getChildren().setAll( createMenuBar(stage, group), zoomPane ); VBox.setVgrow(zoomPane, Priority.ALWAYS); Scene scene = new Scene( layout ); stage.setTitle("Zoomy"); stage.getIcons().setAll(new Image(APP_ICON)); stage.setScene(scene); stage.show(); } private Parent createZoomPane(final Group group) { final double SCALE_DELTA = 1.1; final StackPane zoomPane = new StackPane(); zoomPane.getChildren().add(group); zoomPane.setOnScroll(new EventHandler<ScrollEvent>() { @Override public void handle(ScrollEvent event) { event.consume(); if (event.getDeltaY() == 0) { return; } double scaleFactor = (event.getDeltaY() > 0) ? SCALE_DELTA : 1/SCALE_DELTA; group.setScaleX(group.getScaleX() * scaleFactor); group.setScaleY(group.getScaleY() * scaleFactor); } }); zoomPane.layoutBoundsProperty().addListener(new ChangeListener<Bounds>() { @Override public void changed(ObservableValue<? extends Bounds> observable, Bounds oldBounds, Bounds bounds) { zoomPane.setClip(new Rectangle(bounds.getMinX(), bounds.getMinY(), bounds.getWidth(), bounds.getHeight())); } }); return zoomPane; } private SVGPath createCurve() { SVGPath ellipticalArc = new SVGPath(); ellipticalArc.setContent( "M10,150 A15 15 180 0 1 70 140 A15 25 180 0 0 130 130 A15 55 180 0 1 190 120" ); ellipticalArc.setStroke(Color.LIGHTGREEN); ellipticalArc.setStrokeWidth(4); ellipticalArc.setFill(null); return ellipticalArc; } private SVGPath createStar() { SVGPath star = new SVGPath(); star.setContent( "M100,10 L100,10 40,180 190,60 10,60 160,180 z" ); star.setStrokeLineJoin(StrokeLineJoin.ROUND); star.setStroke(Color.BLUE); star.setFill(Color.DARKBLUE); star.setStrokeWidth(4); return star; } private MenuBar createMenuBar(final Stage stage, final Group group) { Menu fileMenu = new Menu("_File"); MenuItem exitMenuItem = new MenuItem("E_xit"); exitMenuItem.setGraphic(new ImageView(new Image(CLOSE_ICON))); exitMenuItem.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { stage.close(); } }); fileMenu.getItems().setAll( exitMenuItem ); Menu zoomMenu = new Menu("_Zoom"); MenuItem zoomResetMenuItem = new MenuItem("Zoom _Reset"); zoomResetMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.ESCAPE)); zoomResetMenuItem.setGraphic(new ImageView(new Image(ZOOM_RESET_ICON))); zoomResetMenuItem.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { group.setScaleX(1); group.setScaleY(1); } }); MenuItem zoomInMenuItem = new MenuItem("Zoom _In"); zoomInMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.I)); zoomInMenuItem.setGraphic(new ImageView(new Image(ZOOM_IN_ICON))); zoomInMenuItem.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { group.setScaleX(group.getScaleX() * 1.5); group.setScaleY(group.getScaleY() * 1.5); } }); MenuItem zoomOutMenuItem = new MenuItem("Zoom _Out"); zoomOutMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.O)); zoomOutMenuItem.setGraphic(new ImageView(new Image(ZOOM_OUT_ICON))); zoomOutMenuItem.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { group.setScaleX(group.getScaleX() * 1/1.5); group.setScaleY(group.getScaleY() * 1/1.5); } }); zoomMenu.getItems().setAll( zoomResetMenuItem, zoomInMenuItem, zoomOutMenuItem ); MenuBar menuBar = new MenuBar(); menuBar.getMenus().setAll( fileMenu, zoomMenu ); return menuBar; } // icons source from: http://www.iconarchive.com/show/soft-scraps-icons-by-deleket.html // icon license: CC Attribution-Noncommercial-No Derivate 3.0 =? http://creativecommons.org/licenses/by-nc-nd/3.0/ // icon Commercial usage: Allowed (Author Approval required -> Visit artist website for details). public static final String APP_ICON = "http://icons.iconarchive.com/icons/deleket/soft-scraps/128/Zoom-icon.png"; public static final String ZOOM_RESET_ICON = "http://icons.iconarchive.com/icons/deleket/soft-scraps/24/Zoom-icon.png"; public static final String ZOOM_OUT_ICON = "http://icons.iconarchive.com/icons/deleket/soft-scraps/24/Zoom-Out-icon.png"; public static final String ZOOM_IN_ICON = "http://icons.iconarchive.com/icons/deleket/soft-scraps/24/Zoom-In-icon.png"; public static final String CLOSE_ICON = "http://icons.iconarchive.com/icons/deleket/soft-scraps/24/Button-Close-icon.png"; } 

स्क्रॉलपैन में ज़ूम किए गए नोड के लिए अपडेट करें

उपरोक्त क्रियान्वयन, जहां तक ​​जाती है, अच्छी तरह से काम करती है, लेकिन ज़ूम इन नोड को स्क्रॉल फलक के अंदर रखा जा सकता है, ताकि जब आप ज़ूम इन नोड को अपने उपलब्ध व्यूपोर्ट से बड़ा बनाते हैं, तब भी आप अपने आसपास के पैन के आसपास पैन कर सकते हैं नोड के कुछ हिस्सों को देखने के लिए स्क्रॉल फलक के भीतर ज़ूम किए हुए नोड।

मुझे एक स्क्रॉल फलक में ज़ूमिंग के व्यवहार को प्राप्त करना मुश्किल लगता है, इसलिए मैंने ओरेकल जावाएफएक्स फ़ोरम थ्रेड पर मदद के लिए पूछा।

ओरेकल जावाएफ़एक्स फोरम उपयोगकर्ता जेम्स_D निम्नलिखित समाधान के साथ आया है जो एक स्क्रॉलपैन समस्या के भीतर ज़ूमिंग को बहुत अच्छी तरह से हल करता है।

उनकी टिप्पणी और कोड नीचे दिए गए थे:

कुछ नाबालिग परिवर्तन पहले: मैंने स्टेकपैन को एक समूह में लपेट लिया था ताकि ScrollPane को स्क्रॉलपैन जवाडॉक्स के अनुसार परिवर्तनों के बारे में पता चले। और फिर मैं स्टैकपैन के न्यूनतम आकार को व्यूपोर्ट आकार में बांटता हूं (व्यूपोर्ट से छोटा होने पर सामग्री को केंद्रित रखना)।

शुरू में मैंने सोचा कि मैं एक डिस्प्ले का उपयोग करना चाहिए ताकि प्रदर्शित केंद्र के चारों ओर ज़ूम हो सके (अर्थात व्यूपोर्ट के केंद्र में मौजूद सामग्री पर)। लेकिन मुझे लगता है कि मुझे उसी प्रदर्शित केंद्र को रखने के लिए बाद में स्क्रॉल स्थिति को ठीक करने की आवश्यकता है, इसलिए मैंने इसे छोड़ दिया और setScaleX () और setScaleY () का उपयोग करने के लिए वापस लौटा दिया।

चाल स्केलिंग के बाद स्क्रॉल की स्थिति को ठीक करना है। मैंने स्क्रॉल सामग्री के स्थानीय निर्देशांक में ऑफसेट स्क्रॉल की गणना की, और फिर पैमाने के बाद आवश्यक नए स्क्रॉल मानों की गणना की गई। यह थोड़ा मुश्किल था मूल अवलोकन यह है कि (एचवीएलयू-एचएमआईएन) / (एचएमएक्स-एचएमआईएन) = एक्स / (कंटेंटव्यूड-व्यूपोर्टवेडथ), जहां एक्स व्यूोर्ट की बाईं किनारे का क्षैतिज ऑफसेट है, जो सामग्री के बायीं किनारे से है। उसके बाद आपके पास केंद्र X = एक्स + व्यूपोर्ट चौड़ाई 2 है

स्केलिंग के बाद, पुराने केंद्र एक्स के एक्स निर्देशांक अब centerX * scaleFactor है इसलिए हमें नया केंद्र बनाने के लिए नए एचवीएवल को सेट करना होगा। यह पता लगाने के लिए बीजगणित का थोड़ा सा है

उसके बाद, खींचकर पॅनिंग बहुत आसान था :)।

स्क्रॉलपैन में ज़ूमिंग और स्केलिंग कार्यक्षमता का समर्थन करने के लिए उच्च स्तरीय एपीआई जोड़ने के लिए इसी सुविधा का अनुरोध ScrollPane में स्केल कंटेंट कार्यक्षमता जोड़ें अगर आप इसे लागू करना चाहते हैं तो सुविधा के लिए वोट दें या टिप्पणी पर टिप्पणी करें।

 import javafx.application.Application; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.*; import javafx.event.*; import javafx.geometry.Bounds; import javafx.geometry.Point2D; import javafx.scene.*; import javafx.scene.control.*; import javafx.scene.image.*; import javafx.scene.input.*; import javafx.scene.layout.*; import javafx.scene.paint.Color; import javafx.scene.shape.*; import javafx.stage.Stage; public class GraphicsScalingApp extends Application { public static void main(String[] args) { launch(args); } @Override public void start(final Stage stage) { final Group group = new Group(createStar(), createCurve()); Parent zoomPane = createZoomPane(group); VBox layout = new VBox(); layout.getChildren().setAll(createMenuBar(stage, group), zoomPane); VBox.setVgrow(zoomPane, Priority.ALWAYS); Scene scene = new Scene(layout); stage.setTitle("Zoomy"); stage.getIcons().setAll(new Image(APP_ICON)); stage.setScene(scene); stage.show(); } private Parent createZoomPane(final Group group) { final double SCALE_DELTA = 1.1; final StackPane zoomPane = new StackPane(); zoomPane.getChildren().add(group); final ScrollPane scroller = new ScrollPane(); final Group scrollContent = new Group(zoomPane); scroller.setContent(scrollContent); scroller.viewportBoundsProperty().addListener(new ChangeListener<Bounds>() { @Override public void changed(ObservableValue<? extends Bounds> observable, Bounds oldValue, Bounds newValue) { zoomPane.setMinSize(newValue.getWidth(), newValue.getHeight()); } }); scroller.setPrefViewportWidth(256); scroller.setPrefViewportHeight(256); zoomPane.setOnScroll(new EventHandler<ScrollEvent>() { @Override public void handle(ScrollEvent event) { event.consume(); if (event.getDeltaY() == 0) { return; } double scaleFactor = (event.getDeltaY() > 0) ? SCALE_DELTA : 1 / SCALE_DELTA; // amount of scrolling in each direction in scrollContent coordinate // units Point2D scrollOffset = figureScrollOffset(scrollContent, scroller); group.setScaleX(group.getScaleX() * scaleFactor); group.setScaleY(group.getScaleY() * scaleFactor); // move viewport so that old center remains in the center after the // scaling repositionScroller(scrollContent, scroller, scaleFactor, scrollOffset); } }); // Panning via drag.... final ObjectProperty<Point2D> lastMouseCoordinates = new SimpleObjectProperty<Point2D>(); scrollContent.setOnMousePressed(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { lastMouseCoordinates.set(new Point2D(event.getX(), event.getY())); } }); scrollContent.setOnMouseDragged(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent event) { double deltaX = event.getX() - lastMouseCoordinates.get().getX(); double extraWidth = scrollContent.getLayoutBounds().getWidth() - scroller.getViewportBounds().getWidth(); double deltaH = deltaX * (scroller.getHmax() - scroller.getHmin()) / extraWidth; double desiredH = scroller.getHvalue() - deltaH; scroller.setHvalue(Math.max(0, Math.min(scroller.getHmax(), desiredH))); double deltaY = event.getY() - lastMouseCoordinates.get().getY(); double extraHeight = scrollContent.getLayoutBounds().getHeight() - scroller.getViewportBounds().getHeight(); double deltaV = deltaY * (scroller.getHmax() - scroller.getHmin()) / extraHeight; double desiredV = scroller.getVvalue() - deltaV; scroller.setVvalue(Math.max(0, Math.min(scroller.getVmax(), desiredV))); } }); return scroller; } private Point2D figureScrollOffset(Node scrollContent, ScrollPane scroller) { double extraWidth = scrollContent.getLayoutBounds().getWidth() - scroller.getViewportBounds().getWidth(); double hScrollProportion = (scroller.getHvalue() - scroller.getHmin()) / (scroller.getHmax() - scroller.getHmin()); double scrollXOffset = hScrollProportion * Math.max(0, extraWidth); double extraHeight = scrollContent.getLayoutBounds().getHeight() - scroller.getViewportBounds().getHeight(); double vScrollProportion = (scroller.getVvalue() - scroller.getVmin()) / (scroller.getVmax() - scroller.getVmin()); double scrollYOffset = vScrollProportion * Math.max(0, extraHeight); return new Point2D(scrollXOffset, scrollYOffset); } private void repositionScroller(Node scrollContent, ScrollPane scroller, double scaleFactor, Point2D scrollOffset) { double scrollXOffset = scrollOffset.getX(); double scrollYOffset = scrollOffset.getY(); double extraWidth = scrollContent.getLayoutBounds().getWidth() - scroller.getViewportBounds().getWidth(); if (extraWidth > 0) { double halfWidth = scroller.getViewportBounds().getWidth() / 2 ; double newScrollXOffset = (scaleFactor - 1) * halfWidth + scaleFactor * scrollXOffset; scroller.setHvalue(scroller.getHmin() + newScrollXOffset * (scroller.getHmax() - scroller.getHmin()) / extraWidth); } else { scroller.setHvalue(scroller.getHmin()); } double extraHeight = scrollContent.getLayoutBounds().getHeight() - scroller.getViewportBounds().getHeight(); if (extraHeight > 0) { double halfHeight = scroller.getViewportBounds().getHeight() / 2 ; double newScrollYOffset = (scaleFactor - 1) * halfHeight + scaleFactor * scrollYOffset; scroller.setVvalue(scroller.getVmin() + newScrollYOffset * (scroller.getVmax() - scroller.getVmin()) / extraHeight); } else { scroller.setHvalue(scroller.getHmin()); } } private SVGPath createCurve() { SVGPath ellipticalArc = new SVGPath(); ellipticalArc.setContent("M10,150 A15 15 180 0 1 70 140 A15 25 180 0 0 130 130 A15 55 180 0 1 190 120"); ellipticalArc.setStroke(Color.LIGHTGREEN); ellipticalArc.setStrokeWidth(4); ellipticalArc.setFill(null); return ellipticalArc; } private SVGPath createStar() { SVGPath star = new SVGPath(); star.setContent("M100,10 L100,10 40,180 190,60 10,60 160,180 z"); star.setStrokeLineJoin(StrokeLineJoin.ROUND); star.setStroke(Color.BLUE); star.setFill(Color.DARKBLUE); star.setStrokeWidth(4); return star; } private MenuBar createMenuBar(final Stage stage, final Group group) { Menu fileMenu = new Menu("_File"); MenuItem exitMenuItem = new MenuItem("E_xit"); exitMenuItem.setGraphic(new ImageView(new Image(CLOSE_ICON))); exitMenuItem.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { stage.close(); } }); fileMenu.getItems().setAll(exitMenuItem); Menu zoomMenu = new Menu("_Zoom"); MenuItem zoomResetMenuItem = new MenuItem("Zoom _Reset"); zoomResetMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.ESCAPE)); zoomResetMenuItem.setGraphic(new ImageView(new Image(ZOOM_RESET_ICON))); zoomResetMenuItem.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { group.setScaleX(1); group.setScaleY(1); } }); MenuItem zoomInMenuItem = new MenuItem("Zoom _In"); zoomInMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.I)); zoomInMenuItem.setGraphic(new ImageView(new Image(ZOOM_IN_ICON))); zoomInMenuItem.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { group.setScaleX(group.getScaleX() * 1.5); group.setScaleY(group.getScaleY() * 1.5); } }); MenuItem zoomOutMenuItem = new MenuItem("Zoom _Out"); zoomOutMenuItem.setAccelerator(new KeyCodeCombination(KeyCode.O)); zoomOutMenuItem.setGraphic(new ImageView(new Image(ZOOM_OUT_ICON))); zoomOutMenuItem.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { group.setScaleX(group.getScaleX() * 1 / 1.5); group.setScaleY(group.getScaleY() * 1 / 1.5); } }); zoomMenu.getItems().setAll(zoomResetMenuItem, zoomInMenuItem, zoomOutMenuItem); MenuBar menuBar = new MenuBar(); menuBar.getMenus().setAll(fileMenu, zoomMenu); return menuBar; } // icons source from: // http://www.iconarchive.com/show/soft-scraps-icons-by-deleket.html // icon license: CC Attribution-Noncommercial-No Derivate 3.0 =? // http://creativecommons.org/licenses/by-nc-nd/3.0/ // icon Commercial usage: Allowed (Author Approval required -> Visit artist // website for details). public static final String APP_ICON = "http://icons.iconarchive.com/icons/deleket/soft-scraps/128/Zoom-icon.png"; public static final String ZOOM_RESET_ICON = "http://icons.iconarchive.com/icons/deleket/soft-scraps/24/Zoom-icon.png"; public static final String ZOOM_OUT_ICON = "http://icons.iconarchive.com/icons/deleket/soft-scraps/24/Zoom-Out-icon.png"; public static final String ZOOM_IN_ICON = "http://icons.iconarchive.com/icons/deleket/soft-scraps/24/Zoom-In-icon.png"; public static final String CLOSE_ICON = "http://icons.iconarchive.com/icons/deleket/soft-scraps/24/Button-Close-icon.png"; } 

जौज़िया के उत्तर में एक समस्या है, अगर ज़ूमपेन में मूल सामग्री का आकार व्यू पोर्ट से पहले ही बड़ा है। तो निम्न कोड काम नहीं करेगा ज़ूमपैन.सेटमिनसिज़ (नयावॉल्यूजेटविड्थ (), newValue.getHeight ());

परिणाम यह है कि जब हम ज़ूम आउट करते हैं, तब सामग्री को और अधिक केंद्रित नहीं किया जाता है।

इस समस्या को हल करने के लिए, आपको ज़ूमपेन और स्क्रॉलपैन के बीच एक और स्टैकपैन बनाने की आवश्यकता है।

  // Create a zoom pane for zoom in/out final StackPane zoomPane = new StackPane(); zoomPane.getChildren().add(group); final Group zoomContent = new Group(zoomPane); // Create a pane for holding the content, when the content is smaller than the view port, // it will stay the view port size, make sure the content is centered final StackPane canvasPane = new StackPane(); canvasPane.getChildren().add(zoomContent); final Group scrollContent = new Group(canvasPane); // Scroll pane for scrolling scroller = new ScrollPane(); scroller.setContent(scrollContent); 

और व्यूपोर्टबॉउन्सप्रॉपर्टी श्रोता में, ज़ूमपैन को कैनवासपैन पर बदलें

 // Set the minimum canvas size canvasPane.setMinSize(newValue.getWidth(), newValue.getHeight()); 

ज़ूम इन / आउट के लिए जावाएफएक्स बहुत जटिल है। उसी प्रभाव को प्राप्त करने के लिए, WPF बहुत आसान है।