/ / जावाएफएक्स एकल आकार की घटनाओं को प्राप्त कर रहा है - जावा, जावाफैक्स, जावाफैक्स -8, जेवाफैक्स -2

जावाएफएक्स को एकल आकार बदलने की घटनाएं मिल रही हैं - जावा, जावाफक्स, जावाफक्स -8, जावाफक्स -2

यह सवाल बल्कि सरल है: क्या यह संभव है कि आकार बदलने वाली घटनाओं को प्राप्त करें जो केवल एक बार ट्रिगर करते हैं, भले ही width तथा height एक ही समय में परिवर्तन?

मेरे पास एक एप्लिकेशन है जो प्रति पिक्सेल विंडो पिक्सेल के आकार में एक छवि की गणना करता है। जब विंडो आकार बदलती है तो छवि फिर से गणना की जा रही है। समस्या यह है, कि जब सुन रहा हो widthProperty() तथा heightProperty() आग लगने पर हमेशा दो घटनाएं होंगी width तथा height एक ही लूप चक्र में बदल गया। इसके परिणामस्वरूप एक निरर्थक गणना होती है। क्या अद्यतन के अनुसार आकार बदलने के लिए एक तरीका है?

एक सरल उदाहरण:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {
public static void main(String[] args) {
launch(args);
}

@Override
public void start(Stage primaryStage) {
Group root = new Group();

primaryStage.setScene(new Scene(root));
primaryStage.show();

primaryStage.setWidth(800);
primaryStage.setHeight(800);

primaryStage.widthProperty().addListener((observable, oldValue, newValue) ->
System.out.println("old: (" + oldValue + ", " + primaryStage.getHeight() + "); "
+ "new: (" + newValue + ", " + primaryStage.getHeight() + ")")
);

primaryStage.heightProperty().addListener((observable, oldValue, newValue) ->
System.out.println("old: (" + primaryStage.getWidth() + ", " + oldValue + "); "
+ "new: (" + primaryStage.getWidth() + ", " + newValue + ")")
);

primaryStage.setWidth(400);
primaryStage.setHeight(400);
}
}

यह प्रिंट:

old: (800.0, 800.0); new: (400.0, 800.0)
old: (400.0, 800.0); new: (400.0, 400.0)

लेकिन मैं इसे केवल एक आउटपुट के रूप में चाहता हूं:

old: (800.0, 800.0); new: (400.0, 400.0)

उत्तर:

जवाब के लिए 3 № 1

ऐसा करने का कोई अच्छा तरीका नहीं है। आप एक हैक का उपयोग करके बिट के साथ समान प्रभाव डाल सकते हैं Platform.runLater()। यह काम करता है क्योंकि परिवर्तन (चौड़ाई और ऊंचाई) दोनों को एक ही घटना से ट्रिगर किया जाता है, जिसे ए से पहले इसकी संपूर्णता में संसाधित किया जाता है Platform.runLater(...) ट्रिगर किया जा सकता है। चर को शून्य पर सेट करना और परिवर्तनों को अनदेखा करना यदि यह शून्य नहीं है, तो यह सुनिश्चित करता है कि एक ही घटना से कई बदलावों को एक एकल कॉल में ले लिया जाए Platform.runLater().

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {
public static void main(String[] args) {
launch(args);
}

@Override
public void start(Stage primaryStage) {
Group root = new Group();

primaryStage.setScene(new Scene(root));
primaryStage.show();

primaryStage.setWidth(800);
primaryStage.setHeight(800);

ChangeListener<Number> listener = new ChangeListener<Number>() {
private Point2D stageSize = null ;
private Point2D previousStageSize = new Point2D(primaryStage.getWidth(), primaryStage.getHeight());
@Override
public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
if (stageSize == null) {
Platform.runLater(() -> {
System.out.printf("Old: (%.1f, %.1f); new: (%.1f, %.1f)%n",
previousStageSize.getX(), previousStageSize.getY(),
stageSize.getX(), stageSize.getY());
previousStageSize = stageSize;
stageSize = null;
});
}
stageSize = new Point2D(primaryStage.getWidth(), primaryStage.getHeight());
}


};

primaryStage.widthProperty().addListener(listener);
primaryStage.heightProperty().addListener(listener);


primaryStage.setWidth(400);
primaryStage.setHeight(400);
}
}

हालांकि यह यकीनन एक हैक है, प्रसंस्करण केवल तभी बदलता है जब कोई अन्य परिवर्तन लंबित न हों वास्तव में वही हो सकता है जो आप इस उपयोग के मामले में देख रहे हैं।


उत्तर № 2 के लिए 1

श्रोता के साथ नहीं।

यहां तक ​​कि श्रोता को जोड़ने के लिए layoutBounds संपत्ति जीता "टी मदद।

केवल वर्कअराउंड के बारे में मुझे पता है कि ओवरराइडिंग होगी layoutChildren रूट नोड की विधि, जिसे आकार को असाइन करने के बाद लेआउट के दौरान किया जाता है Parent:

Region root = new Region() {

@Override
protected void layoutChildren() {
super.layoutChildren();
System.out.println("new: (" + getWidth() + ", " + getHeight() + ");");
}

};

नोट: JavaFX 9 आपको एक जोड़ने की अनुमति देता है postLayoutPulseListener दृश्य के लिए लेकिन यह तब भी ट्रिगर हो सकता है जब आकार नहीं बदलता है:

scene.addPostLayoutPulseListener(() -> {
System.out.println("new: (" + primaryStage.getWidth() + ", " + primaryStage.getHeight() + ")");
});