IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaFX Discussion :

Extraire les coordonnées d'un point sur un graphe LineChart


Sujet :

JavaFX

  1. #1
    Membre du Club
    Homme Profil pro
    Ingénieur projet
    Inscrit en
    Juin 2014
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur projet
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2014
    Messages : 46
    Points : 43
    Points
    43
    Par défaut Extraire les coordonnées d'un point sur un graphe LineChart
    Bonjour,

    Je développe en JavaFX une interface graphique dans laquelle des séries de données sont affichées dans un graphique ("linechart").
    J'ai besoin de créer une fonction qui permet à l'utilisateur de récupérer les coordonnées d'un point pour une série de données spécifique.
    Cette fonction doit être désactivable.

    Voici une brève description de la fonction que je souhaite développer. Lorsque l'utilisateur active cette option (en cliquant sur un bouton de l'interface) et déplace la souris sur le graphe, un trait vertical suit le déplacement de la souris. Lorsque l'utilisateur à cliqué sur un endroit du graphe, l’abscisse du point sélectionné est retournée au programme qui exploitera cette info.

    Pour commencer, je veux simplement extraire les coordonnées d'un point correspondant à l'endroit où l'utilisateur a cliqué.
    Pour cela, j'ai créé un bouton (boutonSelectedValueInGraph)qui gère l'appel et l'activation de cette fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    boutonSelectedValueInGraph.setOnAction(new EventHandler<ActionEvent>() {
    						@Override 
    						public void handle(ActionEvent event) {
    							UserSelectValue();
    							x1BaselinetextInput.setText(selectedValue.toString());
    						}
    					});
    "x1BaselinetextInput" correspond à un champ dans lequel l’abscisse du point choisi sera affiché. "selectedValue" contient l’abscisse du point. Étant donné que cette fonctionnalité sera employée à plusieurs reprises dans le code, j'ai créé une méthode qui est censée gérer l'extraction de cette valeur. Cette routine s'appelle "UserSelectValue()".

    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
                  private void UserSelectValue(){
    					userSelectedValue = false;  // Variable servant à savoir si l'utilisateur a sélectionné ou non une valeur.
    					selectedValue = null; // Variable dans laquelle est stockée la valeur sélectionnée par l'utilisateur.
     
    					final Axis<Double> xAxis = graph.getXAxis();
    					final Axis<Double> yAxis = graph.getYAxis();
     
    					final Node chartBackground = graph.lookup(".chart-plot-background");
     
    					// On actionne des eventHandler tant qu'une valeur n'a pas été sélectionné par l'utilsateur.
     
    					for (Node n: chartBackground.getParent().getChildrenUnmodifiable()) {
    						if (n != chartBackground && n != xAxis && n != yAxis) {
    							n.setMouseTransparent(true);
    						}
    					}
     
    					if (userSelectedValue == false){
     
    						chartBackground.setOnMouseEntered(new EventHandler<MouseEvent>() {
    							@Override public void handle(MouseEvent mouseEvent) {
    								System.out.println("Mouse Entered");
    								graph.setCursor(Cursor.HAND); //Change cursor to hand
    							}
    						});
     
    						chartBackground.setOnMouseClicked(new EventHandler<MouseEvent>() {
    							@Override public void handle(MouseEvent mouseEvent) {
    								System.out.println("A data have been selected by the user !");
    								selectedValue = Double.valueOf(xAxis.getValueForDisplay(mouseEvent.getX()));
    								userSelectedValue = true;
    								System.out.println("x : "+selectedValue);
     
    							}
    						});
     
    						chartBackground.setOnMouseExited(new EventHandler<MouseEvent>() {
    							@Override public void handle(MouseEvent mouseEvent) {
    								System.out.println("Mouse Exited");
    								graph.setCursor(Cursor.DEFAULT);
    							}
    						});
    					}
    				}
    Pour que cette fonctionnalité soit activable ou désactivable à la demande, j'ai créé une variable "boolean userSelectedValue" qui au moment de lancer cette fonction vaut "false". Tant que l'utilisateur n'a pas sélectionné une valeur, cette valeur n'est pas modifiée.
    Mon problème est que je ne trouve pas le moyen de désactiver cette fonctionnalité.
    En plus de cela, le programme ne semble pas attendre que l'utilisateur sélectionne une valeur pour retourner la valeur stockée dans "selectedValue". Il me retourne donc "null", ce qui génére un message d'erreur dans la fenêtre de commande dès que je clique sur le bouton.

    J'ai tenté de faire en sorte que la fonction "UserSelectValue()" retourne une valeur de type Double ou String, plutôt que d'être de type void.
    Je déclare localement une variable "final String selected = new String();", mais je ne parviens pas à lui affecter une valeur dans
    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
     
    private String UserSelectValue(){
         final String selected = new String();
         ...
         chartBackground.setOnMouseClicked(new EventHandler<MouseEvent>() {
    							@Override public void handle(MouseEvent mouseEvent) {
    								System.out.println("A data have been selected by the user !");
    								selectedValue = Double.valueOf(xAxis.getValueForDisplay(mouseEvent.getX()));
    								selected=xAxis.getValueForDisplay(mouseEvent.getX()).toString();
    								userSelectedValue = true;
    								System.out.println("x : "+selectedValue);
     
    							}
    						});
         ...
         return selected;
    }
    Eclispe me signal une erreur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    The final local variable selected cannot be assigned, since it is defined in an enclosing type
    Il semble que l’utilisation d'un if ne permet pas de désactiver cette commande. L’utilisation d'un boucle While ne fonctionne pas non plus.

    Auriez vous une idée qui me permettrait de contourner ces problèmes pour que cette fonctionnalité soit activée uniquement entre le moment ou je clique sur le bouton jusqu'au moment où une valeur est sélectionnée ?

    Comment faire en sorte que le programme attende que la valeur soit définie pour la retourner au programme ?

    Merci d'avance.

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Bon, j'avoue que je suis un peu perdu dans les explications. Essaie de voir si ceci ne correspond pas un peu mieux a ce que tu voulais faire :

    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    public class TrackLineChart<X extends Number, Y extends Number> extends LineChart<X, Y> {
     
        private final Region userTrackArea = new Region();
        private final Line lineUserTrackX = new Line();
        private final Line lineUserTrackY = new Line();
     
        public TrackLineChart(Axis xAxis, Axis yAxis) {
            super(xAxis, yAxis);
            userTrackXProperty().addListener(observable -> requestChartLayout());
            userTrackYProperty().addListener(observable -> requestChartLayout());
            userTrackArea.setId("userTrackArea");
            userTrackArea.mouseTransparentProperty().bind(trackUserProperty().not());
            userTrackArea.setOnMouseMoved(this::handleMouseTrackingMoved);
            userTrackArea.setOnMouseExited(this::handleTrackingMouseExit);
            userTrackArea.setOnMouseClicked(this::handleMouseTrackingClicked);
            lineUserTrackX.setId("lineUserTrackX");
            lineUserTrackX.visibleProperty().bind(trackUserProperty());
            lineUserTrackY.setId("lineUserTrackY");
            lineUserTrackY.visibleProperty().bind(trackUserProperty());
            getPlotChildren().addAll(lineUserTrackX, lineUserTrackY, userTrackArea);
        }
     
        private void handleMouseTrackingMoved(final MouseEvent mouseEvent) {
            final NumberAxis xAxis = (NumberAxis) getXAxis();
            final NumberAxis yAxis = (NumberAxis) getYAxis();
            final double mouseX = mouseEvent.getX();
            final double mouseY = mouseEvent.getY();
            final double valueX = xAxis.getValueForDisplay(mouseX).doubleValue();
            final double valueY = yAxis.getValueForDisplay(mouseY).doubleValue();
    //        System.out.printf("Mouse %f %f -> value %f (%f %f) %f (%f %f)", mouseX, mouseY,
    //                valueX, xAxis.getLowerBound(), xAxis.getUpperBound(),
    //                valueY, yAxis.getLowerBound(), yAxis.getUpperBound()).println();
            userTrackX.set(valueX);
            userTrackY.set(valueY);
        }
     
        private void handleTrackingMouseExit(final MouseEvent mouseEvent) {
            userTrackX.set(0);
            userTrackY.set(0);
        }
     
        private void handleMouseTrackingClicked(final MouseEvent mouseEvent) {
            final double mouseX = mouseEvent.getX();
            final NumberAxis xAxis = (NumberAxis) getXAxis();
            final double valueX = xAxis.getValueForDisplay(mouseX).doubleValue();
            selectionX.set(valueX);
        }
     
        ////////////////////////////////////////////////////////////////////////////
        @Override
        protected void layoutPlotChildren() {
            super.layoutPlotChildren();
            final NumberAxis xAxis = (NumberAxis) getXAxis();
            final NumberAxis yAxis = (NumberAxis) getYAxis();
            lineUserTrackX.toFront();
            lineUserTrackY.toFront();
            userTrackArea.toFront();
            final Double userTrackXObj = getUserTrackX();
            final double userTrackX = userTrackXObj == null ? 0 : userTrackXObj.doubleValue();
            final Double userTrackYObj = getUserTrackY();
            final double userTrackY = userTrackYObj == null ? 0 : userTrackYObj.doubleValue();
    //        System.out.printf("User %f %f", userTrackX, userTrackY).println();
            final double x = xAxis.getDisplayPosition(userTrackX);
            final double y = yAxis.getDisplayPosition(userTrackY);
            final double x1 = xAxis.getDisplayPosition(xAxis.getLowerBound());
            final double y1 = yAxis.getDisplayPosition(yAxis.getLowerBound());
            final double x2 = xAxis.getDisplayPosition(xAxis.getUpperBound());
            final double y2 = yAxis.getDisplayPosition(yAxis.getUpperBound());
            //
            final double screenOffset = 0.5;
            //
            layoutInArea(userTrackArea, x1, y2, x2 - x1, y1 - y2, 0, HPos.LEFT, VPos.TOP);
            //
            lineUserTrackX.setStartX(x + screenOffset);
            lineUserTrackX.setStartY(y1 + screenOffset);
            lineUserTrackX.setEndX(x + screenOffset);
            lineUserTrackX.setEndY(y2 + screenOffset);
            //
            lineUserTrackY.setStartX(x1 + screenOffset);
            lineUserTrackY.setStartY(y + screenOffset);
            lineUserTrackY.setEndX(x2);
            lineUserTrackY.setEndY(y);
        }
     
        ////////////////////////////////////////////////////////////////////////////
        private final BooleanProperty trackUser = new SimpleBooleanProperty(this, "trackUser", true);
     
        public final boolean isTrackUser() {
            return trackUser.get();
        }
     
        public final void setTrackUser(final boolean value) {
            trackUser.set(value);
        }
     
        public final BooleanProperty trackUserProperty() {
            return trackUser;
        }
     
        private final ReadOnlyDoubleWrapper userTrackX = new ReadOnlyDoubleWrapper(this, "userTrackX");
     
        public final Double getUserTrackX() {
            return userTrackX.get();
        }
     
        public final ReadOnlyDoubleProperty userTrackXProperty() {
            return userTrackX.getReadOnlyProperty();
        }
     
        private final ReadOnlyDoubleWrapper userTrackY = new ReadOnlyDoubleWrapper(this, "userTrackY");
     
        public final Double getUserTrackY() {
            return userTrackY.get();
        }
     
        public final ReadOnlyDoubleProperty userTrackYProperty() {
            return userTrackY.getReadOnlyProperty();
        }
     
        private final ReadOnlyDoubleWrapper selectionX = new ReadOnlyDoubleWrapper(this, "selectionX");
     
        public final Double getSelectionX() {
            return selectionX.get();
        }
     
        public final ReadOnlyDoubleProperty selectionXProperty() {
            return selectionX.getReadOnlyProperty();
        }
    }
    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
        public void start(Stage primaryStage) {
            final List<LineChart.Series> seriesList = new LinkedList<>();
            final int maxN = 3;
            final int minX = 0;
            final int maxX = 5;
            double minY = Double.MAX_VALUE;
            double maxY = -Double.MAX_VALUE;
            for (int n = 0 ; n <= maxN ; n++) {
                final LineChart.Series series  = new LineChart.Series<>();
                series.setName(String.format("n = %d", n));
                for (int x = minX ; x <= maxX ; x++) {
                    final double value = Math.pow(x, n);
                    minY = Math.min(minY, value);
                    maxY = Math.max(maxY, value);
                    final LineChart.Data data = new LineChart.Data(x, value);
                    series.getData().add(data);
                }
                seriesList.add(series);
            }
            final NumberAxis xAxis = new NumberAxis(minX, maxX, 1);
            xAxis.setLabel("x");
            final NumberAxis yAxis = new NumberAxis(minY, maxY, 50);
            yAxis.setLabel("y = Math.pow(x, n)");
            final TrackLineChart chart = new TrackLineChart(xAxis, yAxis);
            chart.setTitle("Fonction puissance");
            chart.getData().setAll(seriesList);
            final CheckBox trackCheck = new CheckBox("Track user");
            trackCheck.setSelected(true);
            chart.trackUserProperty().bind(trackCheck.selectedProperty());
            final ToolBar toolBar = new ToolBar();
            toolBar.getItems().add(trackCheck);
            final BorderPane root = new BorderPane();
            root.setCenter(chart);
            root.setTop(toolBar);
            Scene scene = new Scene(root, 500, 500);
            primaryStage.setTitle("Hello World!");
            primaryStage.setScene(scene);
            primaryStage.show();
            chart.selectionXProperty().addListener(observable -> System.out.printf("Selection %f", chart.getSelectionX()).println());
        }
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Membre du Club
    Homme Profil pro
    Ingénieur projet
    Inscrit en
    Juin 2014
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur projet
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2014
    Messages : 46
    Points : 43
    Points
    43
    Par défaut
    Effectivement, à vouloir trop détailler mon explication, c'est devenu confus et difficile à comprendre.
    C'est exactement ce que je recherche.
    Il me reste plus qu'à adapter tout cela à mon programme.
    Merci beaucoup.

  4. #4
    Membre du Club
    Homme Profil pro
    Ingénieur projet
    Inscrit en
    Juin 2014
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur projet
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2014
    Messages : 46
    Points : 43
    Points
    43
    Par défaut
    J'ai adapté avec succès le code à mon programme. Je rencontre toutefois un problème.
    Je dois extraire du graphe une borne supérieure et une borne inférieure. Pour cela je fais appel à deux boutons différents qui sont censés extraire ces infos.
    Le programme fonctionne correctement lorsque j’extrais une première borne. La valeur choisie est alors stockée dans une variable et affichée dans un champ de texte.
    Lorsque je cherche à sélectionner une seconde borne avec le second bouton, la valeur affectée à la première borne est également modifiée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    boutonSelectedx1BaselineValueInGraph.setOnAction(new EventHandler<ActionEvent>() {
            @Override 
    	public void handle(ActionEvent event) {
            ...
                 graph.selectionXProperty().addListener(observable -> x1BaselinetextInput.setText(graph.getSelectionX().toString()));
            ...
            }
    Avez vous une idée pour contourner ce problème ?
    Merci par avance.

  5. #5
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Il n'y a le code que d'un seul des deux boutons ici.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  6. #6
    Membre du Club
    Homme Profil pro
    Ingénieur projet
    Inscrit en
    Juin 2014
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur projet
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2014
    Messages : 46
    Points : 43
    Points
    43
    Par défaut
    Le code pour le second bouton est identique, seul le nom du champ de destination change. Voici le code pour les deux boutons :
    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
    boutonSelectedx1BaselineValueInGraph.setOnAction(new EventHandler<ActionEvent>() {
            @Override 
    	public void handle(ActionEvent event) {
            ...
                 graph.selectionXProperty().addListener(observable -> x1BaselinetextInput.setText(graph.getSelectionX().toString()));
            ...
            }
    }
     
    boutonSelectedx2BaselineValueInGraph.setOnAction(new EventHandler<ActionEvent>() {
            @Override 
    	public void handle(ActionEvent event) {
            ...
                 graph.selectionXProperty().addListener(observable -> x2BaselinetextInput.setText(graph.getSelectionX().toString()));
            ...
            }
    }

  7. #7
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Ton erreur est, lors du click sur le bouton, de vouloir passer par un listener plutôt que par un accès direct :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    boutonSelectedx1BaselineValueInGraph.disableProperty(Bindings.isNull(graph.selectionXProperty());
    boutonSelectedx2BaselineValueInGraph.disableProperty(Bindings.isNull(graph.selectionXProperty());
     
    boutonSelectedx1BaselineValueInGraph.setOnAction(event -> x1BaselinetextInput.setText(graph.getSelectionX().toString()));
    boutonSelectedx2BaselineValueInGraph.setOnAction(event -> x2BaselinetextInput.setText(graph.getSelectionX().toString()));
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  8. #8
    Membre du Club
    Homme Profil pro
    Ingénieur projet
    Inscrit en
    Juin 2014
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur projet
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2014
    Messages : 46
    Points : 43
    Points
    43
    Par défaut
    Lorsque je copie ces lignes de code dans mon programme Eclipse me retourne un message d'erreur au niveau du ".isNull()"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    boutonSelectedx1BaselineValueInGraph.disableProperty(Bindings.isNull(graph.selectionXProperty());
    Le message d'erreur est le suivant :"The method isNull(ObservableObjectValue<?>) in the type Bindings is not applicable for the arguments (ReadOnlyDoubleProperty)"

    la méthode en question est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public final ReadOnlyDoubleProperty selectionXProperty() {
            return selectionX.getReadOnlyProperty();
    }
    Cette méthode est directement intégrée dans la classe "TrackLineChart" citée plus haut dans le post.

    Du coup, j'ai essayé de modifier la méthode ".setAction" liée au bouton pour qu'il active la fonction, et collecte l’abscisse du point sélectionnée par l'utilisateur. Ensuite lorsque l'utilisateur a sélectionné une valeur, la fonction est désactivée à l'aide d'un addListener. Mon problème c'est que je n'accède pas à valeur sélectionnée avec cette méthode et que la valeur affichée est 0.0, la commande semble ne pas attendre que l'utilisateur clique sur le graphe pour afficher une valeur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    boutonSelectedx1BaselineValueInGraph.setOnAction((event) -> {
    	trackCheck.setSelected(true);  // Commande permettant d'activer la fonction qui permet de collecter une valeur depuis le graphe.
    	x1BaselinetextInput.setText(graph.getSelectionX().toString());   // La valeur sélectionnée par l'utilisateur est transmise à un champ de texte. 
    });
    graph.selectionXProperty().addListener(observable -> trackCheck.setSelected(false)); // Une fois que l'utilisateur a sélectionné une valeur, on désactive la fonction.
    Java et JavaFx sont nouveaux pour moi, et j'avoue que j'ai du mal à comprendre comment fonctionnent et interagissent toutes ces fonctions. J'ai encore pas mal de boulot pour comprendre et assimiler tout cela. En tous cas, merci pour l'aide apportée.

  9. #9
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Une petite erreur de ma part j'avais oublie que les DoubleProperty stockent des littéraux et sont initialisées a zéro.

    Donc :

    • Partout ou, dans le code du graphe, il y a DoubleProperty, le remplacer par ObjectProperty<Double>.
    • Partout ou dans le code du graphe, il y a DoubleWrapper, le remplacer par ObjectWrapper<Double>.


    Ça réglera le problème des propriétés qui ne peuvent pas contenir la valeur null : désormais toutes nos valeurs de tracking et de sélection peuvent contenir la valeur null et sont initialisées a cette valeur.

    Modifier la condition d'affichage dans le constructeur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    lineUserTrackX.visibleProperty().bind(trackUserProperty().and(Bindings.isNotNull(userTrackXProperty)));
    lineUserTrackY.visibleProperty().bind(trackUserProperty().and(Bindings.isNotNull(userTrackYProperty)));
    Les lignes ne seront affichées uniquement si le tracking est actif ET si les valeurs de tracking ne sont pas null.

    Également, quand le curseur sort de la zone, faire le code suivant au lieu de la mise a zéro précédente:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     userTrackX.set(null);
    userTrackY.set(null);
    Ajouter sans arrêt des listeners sur une propriété a chaque clic de bouton n'est pas une bonne idée, voir même mènera a des gazillions de mises a jours du champs texte a a longue a chaque clic...
    Le mieux est de désactiver le bouton tant que la valeur n'est pas bonne, ce que j'essaie de faire.

    EDIT - ok, ce que tu veux faire (démarrer le tacking lors du clic sur le bouton) prend un peu plus de sens avec le dernier bout de code que tu as posté. Ceci devrait mieux faire l'affaire (en plus des changement listes plus haut).

    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
    private final InvalidationListener x1InvalidationListener = observable -> {
        graph.selectionXProperty().removeListener(x1InvalidationListener);
        trackCheck.setSelected(false);
        x1BaselinetextInput.setText(graph.getSelectionX().toString()); 
    };
     
    private final InvalidationListener x2InvalidationListener = observable -> {
        graph.selectionXProperty().removeListener(x2InvalidationListener);
        trackCheck.setSelected(false);
        x2BaselinetextInput.setText(graph.getSelectionX().toString()); 
    };
     
    boutonSelectedx1BaselineValueInGraph.setOnAction(event -> {
            graph.selectionXProperty().addListener(x1InvalidationListener);
    	trackCheck.setSelected(true);
    });
    boutonSelectedx2BaselineValueInGraph.setOnAction(event -> {
            graph.selectionXProperty().addListener(x2InvalidationListener);
    	trackCheck.setSelected(true);
    });
    Ici, on retire le listener une fois la valeur modifiée, ce qui permet d’éviter en avoir 40.000 sur la propriété.

    Et tu peux enlever le code qui désactive l’état disable des boutons puisque du coup on en a pas besoin ici.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  10. #10
    Membre du Club
    Homme Profil pro
    Ingénieur projet
    Inscrit en
    Juin 2014
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur projet
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2014
    Messages : 46
    Points : 43
    Points
    43
    Par défaut
    Lorsque je modifie le code du constructeur, j'ai besoin de déclarer les variables "userTrackXProperty" et "userTrackYProperty". Du coup, je les ai inutilisé en utilisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    private ObservableObjectValue<Double> userTrackXProperty;
    private ObservableObjectValue<Double> userTrackYProperty;
     
    ...
     
    lineUserTrackX.visibleProperty().bind(trackUserProperty().and(Bindings.isNotNull(userTrackXProperty)));
    lineUserTrackY.visibleProperty().bind(trackUserProperty().and(Bindings.isNotNull(userTrackYProperty)));
    Est-ce que cette initialisation convient ?


    Je rencontre également des problèmes lorsque je créé dans le programme les commandes correspondantes aux boutons.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    private final InvalidationListener x1InvalidationListener = observable -> {
        graph.selectionXProperty().removeListener(x1InvalidationListener);
        trackCheck.setSelected(false);
        x1BaselinetextInput.setText(graph.getSelectionX().toString()); 
    };
     
    private final InvalidationListener x2InvalidationListener = observable -> {
        graph.selectionXProperty().removeListener(x2InvalidationListener);
        trackCheck.setSelected(false);
        x2BaselinetextInput.setText(graph.getSelectionX().toString()); 
    };
    Eclipse me retourne une erreur sur "x1InvalidationListener" et sur "x2InvalidationListener" :
    "llegal modifier for the variable x1InvalidationListener; only final is permitted" et "llegal modifier for the variable x2InvalidationListener; only final is permitted".
    Du coup, j'ai tenté de supprimer les déclarations "private", à ce moment c'est dans le ".removeListener(x1InvalidationListener)" qu'il me pose des problèmes avec ces deux variables.

    Avez vous une solution à ce problème ?
    Merci par avance

  11. #11
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    1) Non.

    On doit passer de :

    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
    private final ReadOnlyDoubleWrapper userTrackX = new ReadOnlyDoubleWrapper(this, "userTrackX");
     
    public final ReadOnlyDoubleProperty userTrackXProperty() {
            return userTrackX.getReadOnlyProperty();
    }
     
    private final ReadOnlyDoubleWrapper userTrackY = new ReadOnlyDoubleWrapper(this, "userTrackY");
     
    public final ReadOnlyDoubleProperty userTrackYProperty() {
            return userTrackY.getReadOnlyProperty();
    }
     
    private final ReadOnlyDoubleWrapper selectionX = new ReadOnlyDoubleWrapper(this, "selectionX");
     
    public final ReadOnlyDoubleProperty selectionXProperty() {
            return selectionX.getReadOnlyProperty();
    }
    à

    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
    private ReadOnlyObjectWrapper<Double> userTrackXProperty = new ReadOnlyObjectWrapper(this, "userTrackX");
     
    public final ReadOnlyObjectProperty<Double> userTrackXProperty() {
            return userTrackX.getReadOnlyProperty();
    }
     
    private ReadOnlyObjectWrapper<Double> userTrackYProperty = new ReadOnlyObjectWrapper(this, "userTrackX");
     
    public final ReadOnlyObjectProperty<Double> userTrackYProperty() {
            return userTrackY.getReadOnlyProperty();
    }
     
    private ReadOnlyObjectWrapper<Double> selectionXProperty = new ReadOnlyObjectWrapper(this, "selectionXProperty");
     
    public final ReadOnlyObjectProperty<Double> selectionXPropertyProperty() {
            return selectionXProperty.getReadOnlyProperty();
    }
    2) Eclipse est très con, j'en ai désormais la preuve...
    Bon ceci dit c'est le final que tu supprimer, pas le private.


    Ok je viens de comprendre que ce message idiot et pas clair du tout indique en fait que tu as défini les deux listeners en tant que variable d'une méthode au lieu de les déclarer en tant que membre de ta classe.
    Ceci dit, dans le cas de membres, supprimer private aurait du fonctionner quand même.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  12. #12
    Membre du Club
    Homme Profil pro
    Ingénieur projet
    Inscrit en
    Juin 2014
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur projet
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2014
    Messages : 46
    Points : 43
    Points
    43
    Par défaut
    Effectivement, voici la structure de mon code :
    Mon programme principal simplifié :
    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
     
    package application.view;
     
    import javafx.*;
    ...
     
    public class DataTraitmentController<WorkingDirectory> implements Initializable {
        ...
        // dataToPLot contient les séries de données qui seront affichées dans le graphe
        ObservableList<XYChart.Series<Double, Double>> dataToPLot = FXCollections.observableArrayList();
     
        final NumberAxis xAxis = new NumberAxis();
        final NumberAxis yAxis = new NumberAxis();
        @FXML private TrackLineChart graph = new TrackLineChart(xAxis,yAxis);
     
        ...
        @Override
        public void initialize(URL location, ResourceBundle resources) {
            ...
    	graph.setData(dataToPLot); // On affiche les différentes séries de données importées sous forme de graphe.
    	graph.setCreateSymbols(false);
    	xAxis.setLabel("Time [s]");
    	yAxis.setLabel("Range of the signal [-]");
            ...
            //Lorsque l'utilisateur clique sur un de ces boutons il a la possibilité de sélectionner une valeur directement en cliquant sur le graphe.
    	Button boutonSelectedx1BaselineValueInGraph = new Button("Pick value",new ImageView(image1));  
    	Button boutonSelectedx2BaselineValueInGraph = new Button("Pick value",new ImageView(image1));
     
            TextField x1BaselinetextInput = new TextField(); // Champ de texte dans lequel la première borne choisie doit être affichée
    	TextField x2BaselinetextInput = new TextField(); // Champ de texte dans lequel la seconde borne choisie doit être affichée
     
            ...
     
            private final InvalidationListener x1InvalidationListener = observable -> {
    		graph.selectionXProperty().removeListener(x1InvalidationListener);
    		trackCheck.setSelected(false);
    		x1BaselinetextInput.setText(graph.getSelectionX().toString()); 
    	};
    	private final InvalidationListener x2InvalidationListener = observable -> {
    	       graph.selectionXProperty().removeListener(x2InvalidationListener);
    	       trackCheck.setSelected(false);
           	       x2BaselinetextInput.setText(graph.getSelectionX().toString()); 
    	};
     
    	boutonSelectedx1BaselineValueInGraph.setOnAction(event -> {
    		graph.selectionXProperty().addListener(x1InvalidationListener);
    		trackCheck.setSelected(true);
    	});
    	boutonSelectedx2BaselineValueInGraph.setOnAction(event -> {
    		graph.selectionXProperty().addListener(x2InvalidationListener);
    		trackCheck.setSelected(true);
    	});
            ...
        }
    }
    Class permettant de gérer
    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    package DataTraitment;
     
    import javafx.beans.binding.Bindings;
    import javafx.beans.property.BooleanProperty;
    import javafx.beans.property.ReadOnlyObjectProperty;
    import javafx.beans.property.ReadOnlyObjectWrapper;
    import javafx.beans.property.SimpleBooleanProperty;
    import javafx.beans.value.ObservableObjectValue;
    import javafx.geometry.HPos;
    import javafx.geometry.VPos;
    import javafx.scene.chart.Axis;
    import javafx.scene.chart.LineChart;
    import javafx.scene.chart.NumberAxis;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.Region;
    import javafx.scene.shape.Line;
     
    public class TrackLineChart<X extends Number, Y extends Number> extends LineChart<X,Y>{
     
    	private final Region userTrackArea = new Region();
    	private final Line lineUserTrackX = new Line();
    	private final Line lineUserTrackY = new Line();
    	private ObservableObjectValue<Double> userTrackXProperty;
    	private ObservableObjectValue<Double> userTrackYProperty;
     
    	@SuppressWarnings({ "rawtypes", "unchecked" })
    	public TrackLineChart(Axis xAxis, Axis yAxis) {
    		super(xAxis, yAxis);
    		userTrackXProperty().addListener(observable -> requestChartLayout());
            userTrackYProperty().addListener(observable -> requestChartLayout());
            userTrackArea.setId("userTrackArea");
            userTrackArea.mouseTransparentProperty().bind(trackUserProperty().not());
            userTrackArea.setOnMouseMoved(this::handleMouseTrackingMoved);
            userTrackArea.setOnMouseExited(this::handleTrackingMouseExit);
            userTrackArea.setOnMouseClicked(this::handleMouseTrackingClicked);
            lineUserTrackX.setId("lineUserTrackX");
            lineUserTrackX.visibleProperty().bind(trackUserProperty());
            lineUserTrackY.setId("lineUserTrackY");
            lineUserTrackY.visibleProperty().bind(trackUserProperty());
            getPlotChildren().addAll(lineUserTrackX, lineUserTrackY, userTrackArea);
    	}
     
    	private void handleMouseTrackingMoved(final MouseEvent mouseEvent) {
            final NumberAxis xAxis = (NumberAxis) getXAxis();
            final NumberAxis yAxis = (NumberAxis) getYAxis();
            final double mouseX = mouseEvent.getX();
            final double mouseY = mouseEvent.getY();
            final double valueX = xAxis.getValueForDisplay(mouseX).doubleValue();
            final double valueY = yAxis.getValueForDisplay(mouseY).doubleValue();
    //        System.out.printf("Mouse %f %f -> value %f (%f %f) %f (%f %f)", mouseX, mouseY,
    //                valueX, xAxis.getLowerBound(), xAxis.getUpperBound(),
    //                valueY, yAxis.getLowerBound(), yAxis.getUpperBound()).println();
            lineUserTrackX.visibleProperty().bind(trackUserProperty().and(Bindings.isNotNull(userTrackXProperty)));
            lineUserTrackY.visibleProperty().bind(trackUserProperty().and(Bindings.isNotNull(userTrackYProperty)));
        }
     
        private void handleTrackingMouseExit(final MouseEvent mouseEvent) {
        	userTrackX.set(null);
        	userTrackY.set(null);
        }
     
        private void handleMouseTrackingClicked(final MouseEvent mouseEvent) {
            final double mouseX = mouseEvent.getX();
            final NumberAxis xAxis = (NumberAxis) getXAxis();
            final double valueX = xAxis.getValueForDisplay(mouseX).doubleValue();
            selectionX.set(valueX);
        }
     
        ////////////////////////////////////////////////////////////////////////////
        @Override
        protected void layoutPlotChildren() {
            super.layoutPlotChildren();
            final NumberAxis xAxis = (NumberAxis) getXAxis();
            final NumberAxis yAxis = (NumberAxis) getYAxis();
            lineUserTrackX.toFront();
            lineUserTrackY.toFront();
            userTrackArea.toFront();
            final Double userTrackXObj = getUserTrackX();
            final double userTrackX = userTrackXObj == null ? 0 : userTrackXObj.doubleValue();
            final Double userTrackYObj = getUserTrackY();
            final double userTrackY = userTrackYObj == null ? 0 : userTrackYObj.doubleValue();
    //       System.out.printf("User %f %f", userTrackX, userTrackY).println();
            final double x = xAxis.getDisplayPosition(userTrackX);
            final double y = yAxis.getDisplayPosition(userTrackY);
            final double x1 = xAxis.getDisplayPosition(xAxis.getLowerBound());
            final double y1 = yAxis.getDisplayPosition(yAxis.getLowerBound());
            final double x2 = xAxis.getDisplayPosition(xAxis.getUpperBound());
            final double y2 = yAxis.getDisplayPosition(yAxis.getUpperBound());
            //
            final double screenOffset = 0.5;
            //
            layoutInArea(userTrackArea, x1, y2, x2 - x1, y1 - y2, 0, HPos.LEFT, VPos.TOP);
            //
            lineUserTrackX.setStartX(x + screenOffset);
            lineUserTrackX.setStartY(y1 + screenOffset);
            lineUserTrackX.setEndX(x + screenOffset);
            lineUserTrackX.setEndY(y2 + screenOffset);
            //
            lineUserTrackY.setStartX(x1 + screenOffset);
            lineUserTrackY.setStartY(y + screenOffset);
            lineUserTrackY.setEndX(x2);
            lineUserTrackY.setEndY(y);
        }
     
    	////////////////////////////////////////////////////////////////////////////
        private final BooleanProperty trackUser = new SimpleBooleanProperty(this, "trackUser", true);
     
        public final boolean isTrackUser() {
            return trackUser.get();
        }
     
        public final void setTrackUser(final boolean value) {
            trackUser.set(value);
        }
     
        public final BooleanProperty trackUserProperty() {
            return trackUser;
        }
     
     
     
        private final ReadOnlyObjectWrapper<Double> userTrackX = new ReadOnlyObjectWrapper<Double>(this, "userTrackX");
     
        public final Double getUserTrackX() {
            return userTrackX.get();
        }
     
    	private ReadOnlyObjectProperty<Double> userTrackYProperty() {
    		return userTrackY.getReadOnlyProperty();
    	}
     
     
     
        private final ReadOnlyObjectWrapper<Double> userTrackY = new ReadOnlyObjectWrapper<Double>(this, "userTrackY");
     
        public final Double getUserTrackY() {
            return userTrackY.get();
        }
     
    	private ReadOnlyObjectProperty<Double> userTrackXProperty() {
    		return userTrackX.getReadOnlyProperty();
    	}
     
     
     
        private final ReadOnlyObjectWrapper<Double> selectionX = new ReadOnlyObjectWrapper<Double>(this, "selectionXProperty");
     
        public final Double getSelectionX() {
            return selectionX.get();
        }
     
        public final ReadOnlyObjectProperty<Double> selectionXProperty() {
            return selectionX.getReadOnlyProperty();
        }
     
     
     
    }
    J'ai toujours ce problème récurrent rencontré au niveau de "x1InvalidationListener" et "x2InvalidationListener". Supprimer private ou final ne résous pas le problème. Je suis désolé, mais je ne comprends pas comment/où déclarer les deux listeners en tant que membre de ma classe.

  13. #13
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    En les sortant du corps de la méthode initialize(). Cependant normalement supprimer private et conserver final est suffisant pour les conserver en tant que membre. Je verrai demain (il est bientôt minuit ici).
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  14. #14
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Ok, le soucis vient d'une part du fait que chaque listener se référence lui-même et d'autre part de la notation lambda. Ceci devrait, je l'espere mieux passer :

    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
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        [...]
        final InvalidationListener x1InvalidationListener = new InvalidationListener() {
     
            @Override
            public void invalidated(Observable observable) {
                graph.selectionXProperty().removeListener(this);
                trackCheck.setSelected(false);
                x1BaselinetextInput.setText(graph.getSelectionX().toString());
            }
        };
        final InvalidationListener x2InvalidationListener = new InvalidationListener() {
     
            @Override
            public void invalidated(Observable observable) {
                graph.selectionXProperty().removeListener(this);
                trackCheck.setSelected(false);
                x2BaselinetextInput.setText(graph.getSelectionX().toString());
            }
        };
        boutonSelectedx1BaselineValueInGraph.setOnAction(event -> {
            graph.selectionXProperty().addListener(x1InvalidationListener);
            trackCheck.setSelected(true);
        });
        boutonSelectedx2BaselineValueInGraph.setOnAction(event -> {
            graph.selectionXProperty().addListener(x2InvalidationListener);
            trackCheck.setSelected(true);
        });
    }
    A vérifier bien sur via le débogueur qu'on passe dans le corps des listeneurs une seule et unique fois a chaque clic de bouton.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  15. #15
    Membre du Club
    Homme Profil pro
    Ingénieur projet
    Inscrit en
    Juin 2014
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur projet
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2014
    Messages : 46
    Points : 43
    Points
    43
    Par défaut
    Effectivement cette déclaration permet bien l'exécution du programme. En plus c'est plus clair pour moi dans la compréhension du code.
    Cependant, je n'ai plus d'affichage des lignes verticales et horizontales lorsque je glisse la souris sur le graphe. Pourtant, le programme extrait correctement les coordonnées du curseur.
    Il n'y a pas de problème particulier à la compilation, ni de message d'alerte qui s'affiche dans l'invite de commande.
    Au cas où, je remets le code utilisé pour la classe TrackLineChart.

    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    package DataTraitment;
     
    import javafx.beans.binding.Bindings;
    import javafx.beans.property.BooleanProperty;
    import javafx.beans.property.ReadOnlyObjectProperty;
    import javafx.beans.property.ReadOnlyObjectWrapper;
    import javafx.beans.property.SimpleBooleanProperty;
    import javafx.beans.value.ObservableObjectValue;
    import javafx.geometry.HPos;
    import javafx.geometry.VPos;
    import javafx.scene.chart.Axis;
    import javafx.scene.chart.LineChart;
    import javafx.scene.chart.NumberAxis;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.Region;
    import javafx.scene.shape.Line;
     
    public class TrackLineChart<X extends Number, Y extends Number> extends LineChart<X,Y>{
     
    	private final Region userTrackArea = new Region();
    	private final Line lineUserTrackX = new Line();
    	private final Line lineUserTrackY = new Line();
     
    	@SuppressWarnings({ "rawtypes", "unchecked" })
    	public TrackLineChart(Axis xAxis, Axis yAxis) {
    		super(xAxis, yAxis);
    		userTrackXProperty().addListener(observable -> requestChartLayout());
            userTrackYProperty().addListener(observable -> requestChartLayout());
            userTrackArea.setId("userTrackArea");
            userTrackArea.mouseTransparentProperty().bind(trackUserProperty().not());
            userTrackArea.setOnMouseMoved(this::handleMouseTrackingMoved);
            userTrackArea.setOnMouseExited(this::handleTrackingMouseExit);
            userTrackArea.setOnMouseClicked(this::handleMouseTrackingClicked);
            lineUserTrackX.setId("lineUserTrackX");
            lineUserTrackX.visibleProperty().bind(trackUserProperty());
            lineUserTrackY.setId("lineUserTrackY");
            lineUserTrackY.visibleProperty().bind(trackUserProperty());
            getPlotChildren().addAll(lineUserTrackX, lineUserTrackY, userTrackArea);
    	}
     
    	private void handleMouseTrackingMoved(final MouseEvent mouseEvent) {
            final NumberAxis xAxis = (NumberAxis) getXAxis();
            final NumberAxis yAxis = (NumberAxis) getYAxis();
            final double mouseX = mouseEvent.getX();
            final double mouseY = mouseEvent.getY();
            final double valueX = xAxis.getValueForDisplay(mouseX).doubleValue();
            final double valueY = yAxis.getValueForDisplay(mouseY).doubleValue();
    //        System.out.printf("Mouse %f %f -> value %f (%f %f) %f (%f %f)", mouseX, mouseY,
    //                valueX, xAxis.getLowerBound(), xAxis.getUpperBound(),
    //                valueY, yAxis.getLowerBound(), yAxis.getUpperBound()).println();
            lineUserTrackX.visibleProperty().bind(trackUserProperty().and(Bindings.isNotNull(userTrackXProperty())));
            lineUserTrackY.visibleProperty().bind(trackUserProperty().and(Bindings.isNotNull(userTrackYProperty())));
        }
     
        private void handleTrackingMouseExit(final MouseEvent mouseEvent) {
        	userTrackX.set(null);
        	userTrackY.set(null);
        }
     
        private void handleMouseTrackingClicked(final MouseEvent mouseEvent) {
            final double mouseX = mouseEvent.getX();
            final NumberAxis xAxis = (NumberAxis) getXAxis();
            final double valueX = xAxis.getValueForDisplay(mouseX).doubleValue();
            selectionX.set(valueX);
        }
     
        ////////////////////////////////////////////////////////////////////////////
        @Override
        protected void layoutPlotChildren() {
            super.layoutPlotChildren();
            final NumberAxis xAxis = (NumberAxis) getXAxis();
            final NumberAxis yAxis = (NumberAxis) getYAxis();
            lineUserTrackX.toFront();
            lineUserTrackY.toFront();
            userTrackArea.toFront();
            final Double userTrackXObj = getUserTrackX();
            final double userTrackX = userTrackXObj == null ? 0 : userTrackXObj.doubleValue();
            final Double userTrackYObj = getUserTrackY();
            final double userTrackY = userTrackYObj == null ? 0 : userTrackYObj.doubleValue();
    //       System.out.printf("User %f %f", userTrackX, userTrackY).println();
            final double x = xAxis.getDisplayPosition(userTrackX);
            final double y = yAxis.getDisplayPosition(userTrackY);
            final double x1 = xAxis.getDisplayPosition(xAxis.getLowerBound());
            final double y1 = yAxis.getDisplayPosition(yAxis.getLowerBound());
            final double x2 = xAxis.getDisplayPosition(xAxis.getUpperBound());
            final double y2 = yAxis.getDisplayPosition(yAxis.getUpperBound());
            //
            final double screenOffset = 0.5;
            //
            layoutInArea(userTrackArea, x1, y2, x2 - x1, y1 - y2, 0, HPos.LEFT, VPos.TOP);
            //
            lineUserTrackX.setStartX(x + screenOffset);
            lineUserTrackX.setStartY(y1 + screenOffset);
            lineUserTrackX.setEndX(x + screenOffset);
            lineUserTrackX.setEndY(y2 + screenOffset);
            //
            lineUserTrackY.setStartX(x1 + screenOffset);
            lineUserTrackY.setStartY(y + screenOffset);
            lineUserTrackY.setEndX(x2);
            lineUserTrackY.setEndY(y);
        }
     
    	////////////////////////////////////////////////////////////////////////////
        private final BooleanProperty trackUser = new SimpleBooleanProperty(this, "trackUser", true);
     
        public final boolean isTrackUser() {
            return trackUser.get();
        }
     
        public final void setTrackUser(final boolean value) {
            trackUser.set(value);
        }
     
        public final BooleanProperty trackUserProperty() {
            return trackUser;
        }
     
     
     
        private final ReadOnlyObjectWrapper<Double> userTrackX = new ReadOnlyObjectWrapper<Double>(this, "userTrackX");
     
        public final Double getUserTrackX() {
            return userTrackX.get();
        }
     
    	private ReadOnlyObjectProperty<Double> userTrackYProperty() {
    		return userTrackY.getReadOnlyProperty();
    	}
     
     
     
        private final ReadOnlyObjectWrapper<Double> userTrackY = new ReadOnlyObjectWrapper<Double>(this, "userTrackY");
     
        public final Double getUserTrackY() {
            return userTrackY.get();
        }
     
    	private ReadOnlyObjectProperty<Double> userTrackXProperty() {
    		return userTrackX.getReadOnlyProperty();
    	}
     
     
     
        private final ReadOnlyObjectWrapper<Double> selectionX = new ReadOnlyObjectWrapper<Double>(this, "selectionXProperty");
     
        public final Double getSelectionX() {
            return selectionX.get();
        }
     
        public final ReadOnlyObjectProperty<Double> selectionXProperty() {
            return selectionX.getReadOnlyProperty();
        }
     
     
     
    }

    Par rapport à la précédente version fournie, j'ai simplement remplacé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    lineUserTrackX.visibleProperty().bind(trackUserProperty().and(Bindings.isNotNull(userTrackXProperty)));
    lineUserTrackY.visibleProperty().bind(trackUserProperty().and(Bindings.isNotNull(userTrackYProperty)));
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    lineUserTrackX.visibleProperty().bind(trackUserProperty().and(Bindings.isNotNull(userTrackXProperty())));
    lineUserTrackY.visibleProperty().bind(trackUserProperty().and(Bindings.isNotNull(userTrackYProperty())));
    dans le code plutôt que d'utiliser une décalartion qui ne fonctionnait pas. La différence se situe au niveau de userTrackXProperty()

  16. #16
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Effectivement, tu sembles avoir un soucis pour conceptualiser quand utiliser les propriétés... vu que tu avais enlevé la partie qui met à jour les valeurs des propriétés, les lignes ne pouvaient pas se dessiner.

    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
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    package test;
     
    import javafx.beans.binding.Bindings;
    import javafx.beans.property.BooleanProperty;
    import javafx.beans.property.ReadOnlyObjectProperty;
    import javafx.beans.property.ReadOnlyObjectWrapper;
    import javafx.beans.property.SimpleBooleanProperty;
    import javafx.geometry.HPos;
    import javafx.geometry.VPos;
    import javafx.scene.chart.Axis;
    import javafx.scene.chart.LineChart;
    import javafx.scene.chart.NumberAxis;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.Region;
    import javafx.scene.shape.Line;
     
    public class TrackLineChart<X extends Number, Y extends Number> extends LineChart<X, Y> {
     
        private final Region userTrackArea = new Region();
        private final Line lineUserTrackX = new Line();
        private final Line lineUserTrackY = new Line();
     
        @SuppressWarnings({"rawtypes", "unchecked"})
        public TrackLineChart(Axis xAxis, Axis yAxis) {
            super(xAxis, yAxis);
            userTrackXProperty().addListener(observable -> requestChartLayout());
            userTrackYProperty().addListener(observable -> requestChartLayout());
            userTrackArea.setId("userTrackArea");
            userTrackArea.mouseTransparentProperty().bind(trackUserProperty().not());
            userTrackArea.setOnMouseMoved(this::handleMouseTrackingMoved);
            userTrackArea.setOnMouseExited(this::handleTrackingMouseExit);
            userTrackArea.setOnMouseClicked(this::handleMouseTrackingClicked);
            lineUserTrackX.setId("lineUserTrackX");
            lineUserTrackX.visibleProperty().bind(trackUserProperty());
            lineUserTrackY.setId("lineUserTrackY");
            lineUserTrackY.visibleProperty().bind(trackUserProperty());
            getPlotChildren().addAll(lineUserTrackX, lineUserTrackY, userTrackArea);
            lineUserTrackX.visibleProperty().bind(trackUserProperty().and(Bindings.isNotNull(userTrackXProperty())));
            lineUserTrackY.visibleProperty().bind(trackUserProperty().and(Bindings.isNotNull(userTrackYProperty())));
        }
     
        private void handleMouseTrackingMoved(final MouseEvent mouseEvent) {
            final NumberAxis xAxis = (NumberAxis) getXAxis();
            final NumberAxis yAxis = (NumberAxis) getYAxis();
            final double mouseX = mouseEvent.getX();
            final double mouseY = mouseEvent.getY();
            final double valueX = xAxis.getValueForDisplay(mouseX).doubleValue();
            final double valueY = yAxis.getValueForDisplay(mouseY).doubleValue();
    //        System.out.printf("Mouse %f %f -> value %f (%f %f) %f (%f %f)", mouseX, mouseY,
    //                valueX, xAxis.getLowerBound(), xAxis.getUpperBound(),
    //                valueY, yAxis.getLowerBound(), yAxis.getUpperBound()).println();
            userTrackX.set(valueX);
            userTrackY.set(valueY);
        }
     
        private void handleTrackingMouseExit(final MouseEvent mouseEvent) {
            userTrackX.set(null);
            userTrackY.set(null);
        }
     
        private void handleMouseTrackingClicked(final MouseEvent mouseEvent) {
            final double mouseX = mouseEvent.getX();
            final NumberAxis xAxis = (NumberAxis) getXAxis();
            final double valueX = xAxis.getValueForDisplay(mouseX).doubleValue();
            selectionX.set(valueX);
        }
     
        ////////////////////////////////////////////////////////////////////////////
        @Override
        protected void layoutPlotChildren() {
            super.layoutPlotChildren();
            final NumberAxis xAxis = (NumberAxis) getXAxis();
            final NumberAxis yAxis = (NumberAxis) getYAxis();
            lineUserTrackX.toFront();
            lineUserTrackY.toFront();
            userTrackArea.toFront();
            final Double userTrackXObj = getUserTrackX();
            final double userTrackX = userTrackXObj == null ? 0 : userTrackXObj.doubleValue();
            final Double userTrackYObj = getUserTrackY();
            final double userTrackY = userTrackYObj == null ? 0 : userTrackYObj.doubleValue();
    //       System.out.printf("User %f %f", userTrackX, userTrackY).println();
            final double x = xAxis.getDisplayPosition(userTrackX);
            final double y = yAxis.getDisplayPosition(userTrackY);
            final double x1 = xAxis.getDisplayPosition(xAxis.getLowerBound());
            final double y1 = yAxis.getDisplayPosition(yAxis.getLowerBound());
            final double x2 = xAxis.getDisplayPosition(xAxis.getUpperBound());
            final double y2 = yAxis.getDisplayPosition(yAxis.getUpperBound());
            //
            final double screenOffset = 0.5;
            //
            layoutInArea(userTrackArea, x1, y2, x2 - x1, y1 - y2, 0, HPos.LEFT, VPos.TOP);
            //
            lineUserTrackX.setStartX(x + screenOffset);
            lineUserTrackX.setStartY(y1 + screenOffset);
            lineUserTrackX.setEndX(x + screenOffset);
            lineUserTrackX.setEndY(y2 + screenOffset);
            //
            lineUserTrackY.setStartX(x1 + screenOffset);
            lineUserTrackY.setStartY(y + screenOffset);
            lineUserTrackY.setEndX(x2);
            lineUserTrackY.setEndY(y);
        }
     
        ////////////////////////////////////////////////////////////////////////////
        private final BooleanProperty trackUser = new SimpleBooleanProperty(this, "trackUser", true);
     
        public final boolean isTrackUser() {
            return trackUser.get();
        }
     
        public final void setTrackUser(final boolean value) {
            trackUser.set(value);
        }
     
        public final BooleanProperty trackUserProperty() {
            return trackUser;
        }
     
        private final ReadOnlyObjectWrapper<Double> userTrackX = new ReadOnlyObjectWrapper<Double>(this, "userTrackX");
     
        public final Double getUserTrackX() {
            return userTrackX.get();
        }
     
        private ReadOnlyObjectProperty<Double> userTrackYProperty() {
            return userTrackY.getReadOnlyProperty();
        }
     
        private final ReadOnlyObjectWrapper<Double> userTrackY = new ReadOnlyObjectWrapper<Double>(this, "userTrackY");
     
        public final Double getUserTrackY() {
            return userTrackY.get();
        }
     
        private ReadOnlyObjectProperty<Double> userTrackXProperty() {
            return userTrackX.getReadOnlyProperty();
        }
     
        private final ReadOnlyObjectWrapper<Double> selectionX = new ReadOnlyObjectWrapper<Double>(this, "selectionXProperty");
     
        public final Double getSelectionX() {
            return selectionX.get();
        }
     
        public final ReadOnlyObjectProperty<Double> selectionXProperty() {
            return selectionX.getReadOnlyProperty();
        }
     
    }
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  17. #17
    Membre du Club
    Homme Profil pro
    Ingénieur projet
    Inscrit en
    Juin 2014
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur projet
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2014
    Messages : 46
    Points : 43
    Points
    43
    Par défaut
    Effectivement, maintenant que le problème est soulevé, ça me parait évident.
    Encore un grand merci pour toute l'aide apporté et le temps consacré à enrichir ce forum.

Discussions similaires

  1. [XL-2010] Récupérer les coordonnées d'un point sur un graphique d'un simple clic
    Par leblesois dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 17/03/2014, 18h46
  2. Réponses: 3
    Dernier message: 13/04/2012, 11h59
  3. Trouver les coordonnées d'un point sur une surface NURBS
    Par oodini dans le forum Mathématiques
    Réponses: 2
    Dernier message: 25/05/2011, 18h35
  4. [XL-2003] Obtenir les coordonnées d'un point dans un graph en cliquant dessus
    Par triaguae dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 15/12/2010, 11h09
  5. Réponses: 4
    Dernier message: 27/11/2006, 18h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo