Bonjour,
je rencontre des problèmes avec le code que je développe.
Des séries de données sont stockées sous forme de ObservableList<XYChart.Series<Double, Double>> et sont affichées dans un graphe.
Les propriétés du graphe sont gérées dans une classe à part "TrackLineChart.java".
Pour compléter les fonctionnalités d'affichage des données dans le graphe, j'ai ajouté un bouton zoom dans ma classe principale.
Lorsque je clique sur le bouton zoom, cela active une checkbox qui est liée aux propriétés de la fonction de zoom dans la classe "TrackLineChart.java"
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 final CheckBox zoomSelectionCheck = new CheckBox("Zoom by selection"); final Button zoomButton = new Button("Zoom"); // Commande permettant à l'utilisateur de zoomer sur une zone qu'il sélectionne sous forme d'un rectangle final InvalidationListener zoomSelectionInvalidationListener = new InvalidationListener() { @Override public void invalidated(Observable observable) { graph.zoomSelectionUserProperty().removeListener(this); zoomSelectionCheck.setSelected(false); System.out.println(graph.zoomSelectionUserProperty().get() + "=> Arrêt de la fonction zoom"); } }; zoomButton.setOnAction(event -> { zoomSelectionCheck.setSelected(true); System.out.println(graph.zoomSelectionUserProperty().get()+ "=> Début de la fonction zoom"); graph.zoomSelectionUserProperty().addListener(zoomSelectionInvalidationListener); }); // On lie la fonction de zoom du graphe à la checkbox "zoomSelectionCheck " qui est activée lorsque l'utilisateur clique sur le bouton "zoomButton" graph.zoomSelectionUserProperty().bind(zoomSelectionCheck.selectedProperty());
la fonction de zoom remplit bien son rôle puisque les bornes se redéfinissent correctement.
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 public class TrackLineChart<X extends Number, Y extends Number> extends LineChart<X, Y> { ... private final Rectangle zoomRect = new Rectangle(); private final Region userZoomArea = new Region(); ... @SuppressWarnings({"rawtypes", "unchecked"}) public TrackLineChart(Axis xAxis, Axis yAxis) { super(xAxis, yAxis); ... userZoomArea.setId("userZoomArea"); userZoomArea.setOnMousePressed(this::handleZoomSelectionClicked); userZoomArea.setOnMouseDragged(this::handleZoomSelectionMoved); userZoomArea.setOnMouseExited(this::handleZoomSelectionExited); userZoomArea.setOnMouseClicked(this::doZoom); zoomSelectionUserProperty().addListener(observable -> requestChartLayout()); zoomRect.setId("zoomRect"); zoomRect.visibleProperty().bind(zoomSelectionUserProperty()); zoomRect.setFill(Color.TRANSPARENT); zoomRect.setStroke(Color.RED); } ... // Dans un premier temps, l'utilisateur définie les bornes d'un rectangle qui sert à fixer les nouvelles limites du graphe via plusieurs méthodes qui ne sont pas affichées ici pour ne pas surcharger la lecture du code. ... // Lorsque l'utilisateur relache le bouton de la souris, on exécute la routine de redéfinission des échelles du graphe. private void doZoom(final MouseEvent mouseEvent){ if (zoomSelectionUserProperty().get() == true){ resize(); } } // Routine qui gére la redéfinition des bornes du graphe. private void resize(){ if ((zoomRect.getWidth() != 0.0) && (zoomRect.getHeight() != 0.0)){ System.out.println("Redimensionnement de la fenêtre"); setAutoRanging(false); final NumberAxis xAxis = (NumberAxis) getXAxis(); final NumberAxis yAxis = (NumberAxis) getYAxis(); final double mouseX = zoomRect.getX(); final double mouseY = zoomRect.getY(); final double valueX = xAxis.getValueForDisplay(mouseX).doubleValue(); final double valueY = yAxis.getValueForDisplay(mouseY).doubleValue(); final double valueXBottomRight = xAxis.getValueForDisplay(mouseX+zoomRect.getWidth()).doubleValue(); final double valueYBottomRight = yAxis.getValueForDisplay(mouseY+zoomRect.getHeight()).doubleValue(); Point2D zoomTopLeft = new Point2D(valueX,valueY); Point2D zoomBottomRight = new Point2D(valueXBottomRight, valueYBottomRight); xAxis.setLowerBound(zoomTopLeft.getX()); xAxis.setUpperBound(zoomBottomRight.getX()); yAxis.setLowerBound(zoomBottomRight.getY()); yAxis.setUpperBound(zoomTopLeft.getY()); System.out.println("Redimensionnement de la fenêtre => terminé"); zoomRect.setWidth(0.0); zoomRect.setHeight(0.0); setZoomSelectionUser(false); } } ... private final BooleanPropertyBase zoomSelectionUser = new SimpleBooleanProperty(this, "zoomSelectionUserProperty", false); public final boolean isZoomSelectionUser() { return zoomSelectionUser.get(); } public final void setZoomSelectionUser(final boolean value) { zoomSelectionUser.set(value); } public final BooleanProperty zoomSelectionUserProperty() { return zoomSelectionUser; } ... }
En revanche, la commande "setZoomSelectionUser(false);" qui est censée permettre de désactiver automatiquement la fonction de zoom en désactivant la checkbox de la classe principale retourne une erreur.
Du coup, la fonction de zoom reste activée en permanence à partir du moment où l'on clique au moins une fois sur le bouton zoom.
D'après ce que j'ai compris, ce problème vient du binding entre la checkbox et les propriétés "BooleanPropertyBase". Comme cette propriété, est déjà liée, on ne peut pas modifier cette propriété via la commande "setZoomSelectionUser(false);".
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 Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: A bound value cannot be set. at javafx.beans.property.BooleanPropertyBase.set(Unknown Source) at DataTraitment.TrackLineChart.setZoomSelectionUser(TrackLineChart.java:553) at DataTraitment.TrackLineChart.resize(TrackLineChart.java:428) at DataTraitment.TrackLineChart.doZoom(TrackLineChart.java:395) at DataTraitment.TrackLineChart$$Lambda$242/752239647.handle(Unknown Source) at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source) at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source) at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source) at javafx.event.Event.fireEvent(Unknown Source) at javafx.scene.Scene$ClickGenerator.postProcess(Unknown Source) at javafx.scene.Scene$ClickGenerator.access$7900(Unknown Source) at javafx.scene.Scene$MouseHandler.process(Unknown Source) at javafx.scene.Scene$MouseHandler.access$1500(Unknown Source) at javafx.scene.Scene.impl_processMouseEvent(Unknown Source) at javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source) at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source) at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source) at com.sun.glass.ui.View.handleMouseEvent(Unknown Source) at com.sun.glass.ui.View.notifyMouse(Unknown Source) at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.lambda$null$141(Unknown Source) at com.sun.glass.ui.win.WinApplication$$Lambda$37/1109371569.run(Unknown Source) at java.lang.Thread.run(Unknown Source)
Comment puis-je contourner ce problème.
Merci d'avance
Partager