में नोड को उठाएं और ले जाएं, मैं ScrollPane
के अंदर कुछ घटकों को रखने की कोशिश कर रहा हूं। इन घटकों में माउस द्वारा इस फलक में स्थानांतरित होने की क्षमता होनी चाहिए (क्लिक करें और खींचें)। ScrollPane
स्वयं पैनबल और ज़ूम करने योग्य है।एक पैनबल/ज़ूम करने योग्य फलक
अब अगर मैं उनमें से एक चुनता हूं और इसे एक नई स्थिति में खींचता हूं तो माउस ज़ूम आउट होने पर घटक से तेज़ होता है। जब ज़ूम इन किया जाता है, तो माउस माउस आंदोलन से तेज़ी से स्थानांतरित हो जाता है।
यदि ज़ूम नहीं किया जाता है तो यह तब तक काम करता है जब तक कि मैं एक निश्चित स्थिति तक नहीं पहुंच जाता जहां ScrollPane
स्वचालित रूप से पैन करता है।
इसे नोड्स के निर्धारित निर्देशांक के साथ कुछ करना होगा। क्या किसी को यह पता है कि इसे सही तरीके से काम करने के लिए मुझे क्या जोड़ना है?
मेरे नियंत्रक वर्ग:
public class MainWindowController implements Initializable {
private final double SCALE_DELTA = 1.1;
private final StackPane zoomPane = new StackPane();
private Group group = new Group();
@FXML
private ScrollPane scrollPane;
@Override
public void initialize(URL url, ResourceBundle rb) {
Node node1 = new Node("Test");
Node node2 = new Node("Test2", 100, 200);
group.getChildren().addAll(node1, node2);
zoomPane.getChildren().add(group);
Group scrollContent = new Group(zoomPane);
scrollPane.setContent(scrollContent);
scrollPane.viewportBoundsProperty().addListener((ObservableValue<? extends Bounds> observable,
Bounds oldValue, Bounds newValue) -> {
zoomPane.setMinSize(newValue.getWidth(), newValue.getHeight());
});
zoomPane.setOnScroll(
(ScrollEvent event) -> {
event.consume();
if (event.getDeltaY() == 0) {
return;
}
double scaleFactor = (event.getDeltaY() > 0) ? SCALE_DELTA : 1/SCALE_DELTA;
Point2D scrollOffset = figureScrollOffset(scrollContent, scrollPane);
group.setScaleX(group.getScaleX() * scaleFactor);
group.setScaleY(group.getScaleY() * scaleFactor);
repositionScroller(scrollContent, scrollPane, scaleFactor, scrollOffset);
}
);
group.getChildren()
.add(new Node("Test3", 500, 500));
}
private Point2D figureScrollOffset(javafx.scene.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(javafx.scene.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());
}
}
}
नोड वर्ग:
public class Node extends Parent {
private NodeStatus status = NodeStatus.OK;
private final Image okImage = new Image(getClass().getResourceAsStream("/images/MasterOK.png"));
private ImageView image = new ImageView(okImage);
private final Text label = new Text();
private final Font font = Font.font("Courier", 20);
double orgSceneX, orgSceneY;
double layoutX, layoutY;
public Node(String labelText) {
this(labelText, 0, 0);
}
public Node(String labelText, double x, double y) {
label.setText(labelText);
label.setFont(font);
label.setLayoutX(okImage.getWidth() + 10);
label.setLayoutY(okImage.getHeight()/2 + 10);
getChildren().add(image);
getChildren().add(label);
setLayoutX(x);
setLayoutY(y);
setCursor(Cursor.MOVE);
setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
orgSceneX = t.getSceneX();
orgSceneY = t.getSceneY();
layoutX = getLayoutX();
layoutY = getLayoutY();
}
});
setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
setLayoutX(layoutX + t.getSceneX() - orgSceneX);
setLayoutY(layoutY + t.getSceneY() - orgSceneY);
}
});
}
public NodeStatus getStatus() {
return status;
}
public void setStatus(NodeStatus status) {
this.status = status;
}
}
class Delta {
double x, y;
}
और fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import nodes.*?>
<AnchorPane id="AnchorPane" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cqsmonitor.MainWindowController">
<children>
<Pane layoutX="666.0" layoutY="14.0" prefHeight="572.0" prefWidth="114.0" AnchorPane.bottomAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
<children>
<TextField layoutY="30.0" prefHeight="25.0" prefWidth="114.0" />
<Label layoutY="12.0" text="Search:" />
<ChoiceBox layoutY="90.0" prefHeight="25.0" prefWidth="114.0" />
<Label layoutY="73.0" text="View:" />
</children>
</Pane>
<ScrollPane fx:id="scrollPane" layoutX="14.0" layoutY="14.0" pannable="true" prefHeight="571.0" prefWidth="644.0" AnchorPane.bottomAnchor="15.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="142.0" AnchorPane.topAnchor="14.0">
</ScrollPane>
</children>
</AnchorPane>
धन्यवाद। मैं इस पर एक नज़र डालूँगा। –
यह बॉक्स से बाहर काम करता है। मैं इसे अपने कोड में लागू करने की कोशिश करूंगा और एक बार अपडेट कर दूंगा जब मेरे पास इसका एहसास हो। –
यह बहुत उपयोगी था, धन्यवाद! मैंने आपका उदाहरण इस्तेमाल किया है और इसमें मेरा नोड (एक समूह) जोड़ा है। ज़ूम भी पूरी तरह से काम करता है! मेरे पास एक प्रश्न है हालांकि: क्या फलक ज़ूम करना संभव है, बिना अपने बच्चों को ज़ूम करने और फलक के अंदर अपनी स्थिति का मिलान करना? Google मानचित्र मार्कर के बारे में सोचें।जब आप ज़ूम इन करते हैं, तो मार्कर बड़ा नहीं होता है। मैं इसे कैसे प्राप्त कर सकता हूं? – user3804769