PieChart (JavaFx) 没有在事件上显示我的标签 - JavaFx

PieChart (JavaFx) didn't display my Label on Event - JavaFx

我尝试为我的饼图创建点击标签,但不幸的是我的标签永远不可见。

我在 Whosebug 上发现了一个类似的主题:Label not showing on mouse event JavaFx 但我的应用程序并不那么简单。由于我的架构,我无法将我的标签添加到子列表中。

(您可以在此处找到图表:http://i.stack.imgur.com/ZFJaR.png)

这是我的代码:

PieChartNode.java

    package nodeStatsVision.chartFactory;

    import java.util.ArrayList;
    import javafx.application.Platform;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.EventHandler;
    import javafx.scene.Node;
    import javafx.scene.chart.PieChart;
    import javafx.scene.control.Label;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.paint.Color;
    import nodeStatsVision.beans.ListRepere;
    import nodeStatsVision.beans.OptionsChart;
    import nodeStatsVision.beans.ValueStat;

    /**
     *
     * @author Zombkey.
     */
    public class PieChartNode implements ChartNode {

    private ListRepere categories;
    private ArrayList<ValueStat> values;

    private ObservableList<PieChart.Data> pieChartData; 
    private Node node;

    public PieChartNode(ListRepere categories, ArrayList<ValueStat> values){
            this.categories = categories;
            this.values = values;

            pieChartData = FXCollections.observableArrayList();
            node = new PieChart(pieChartData);

            Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                            formatData();
                    }
            });
    }

    private void formatData() {
            final Label caption = new Label("");
            caption.setTextFill(Color.DARKORANGE);
            caption.setStyle("-fx-font: 24 arial;");                

            for(ValueStat v : values){
                    PieChart.Data dataTemp = new PieChart.Data(v.getCategorie().getStringName(),v.getDoubleValue());
                    pieChartData.add(dataTemp);

                    dataTemp.getNode().addEventHandler(MouseEvent.MOUSE_CLICKED,
                    new EventHandler<MouseEvent>() {
                            @Override public void handle(MouseEvent e) {
                                    System.out.println("event : "+v.getCategorie().getStringName()+" : "+v.getDoubleValue());

                                    caption.setTranslateX(e.getSceneX());
                                    caption.setTranslateY(e.getSceneY());
                                    caption.setText(String.valueOf(dataTemp.getPieValue()));
                                    caption.setVisible(true);
                                    System.out.println("label "+caption);
                            }
                    });
            }
    }

    @Override
    public Node getNodeGraph() {
            return node;
    }

    @Override
    public void setOptions(OptionsChart optionsChart) {
            //To implemente
    }

    }

你知道如何将我的标签添加到场景中吗?

谢谢!

(另一个问题,为什么PieChart.Data的节点是只读的?)

僵尸钥匙。

PS : 对不起我的英语不好,我是法语学生,我还在学习:) Ps 2 : 第一次上 Whosebug,如果我做错了,请告诉我!

您创建并设计了名为 captionLabel,但从未将其添加到 SceneGraph。

必须在某处添加到 Parent 元素,否则将不会显示。

您的 PieChart 已添加到父元素,否则将不会显示。所有其他 JavaFX Nodes.

的方式相同

关于第二个问题,请阅读 JavaDocs:

Readonly access to the node that represents the pie slice. You can use this to add mouse event listeners etc.

好的!我为我的案例找到了解决方案!

从语义上讲,我的 Label 仅适用于我的 PieChart。这就是为什么我不想把它放到我的 SceneGraph 中。 我的ChartFactoryreturn一个Node,然后显示出来。所以我的节点必须包含 PieChartLabel.

我用 StackPane 创建了一个 Group。在 StackPane 中,我添加了我的 PieChart 和我的 Label。然后我厂return把Group当成了Node.

放下代码!

    package nodeStatsVision.chartFactory;

    import java.util.ArrayList;
    import javafx.application.Platform;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.EventHandler;
    import javafx.scene.Group;
    import javafx.scene.Node;
    import javafx.scene.Parent;
    import javafx.scene.chart.PieChart;
    import javafx.scene.control.Label;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.StackPane;
    import javafx.scene.paint.Color;
    import nodeStatsVision.beans.ListRepere;
    import nodeStatsVision.beans.OptionsChart;
    import nodeStatsVision.beans.ValueStat;

    /**
     *
     * @author Zombkey.
     */
    public class PieChartNode implements ChartNode {

    private ListRepere categories;
    private ArrayList<ValueStat> values;

    private ObservableList<PieChart.Data> pieChartData; 
    private Group group;
    private Node node;
    private final Label caption;

    public PieChartNode(ListRepere categories, ArrayList<ValueStat> values){
            this.categories = categories;
            this.values = values;

            group = new Group();
            StackPane pane = new StackPane();
            group.getChildren().add(pane);

            pieChartData = FXCollections.observableArrayList();
            node = new PieChart(pieChartData);
            pane.getChildren().add(node);

            caption = new Label("");
            caption.setVisible(false);
            caption.getStyleClass().addAll("chart-line-symbol", "chart-series-line");
            caption.setStyle("-fx-font-size: 12; -fx-font-weight: bold;");
            caption.setMinSize(Label.USE_PREF_SIZE, Label.USE_PREF_SIZE);
            pane.getChildren().add(caption);

            Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                            formatData();
                    }
            });
    }

    private void formatData() {

            for(ValueStat v : values){
                    PieChart.Data dataTemp = new PieChart.Data(v.getCategorie().getStringName(),v.getDoubleValue());
                    pieChartData.add(dataTemp);

                    dataTemp.getNode().addEventHandler(MouseEvent.MOUSE_ENTERED,
                    new EventHandler<MouseEvent>() {
                            @Override public void handle(MouseEvent e) {
                                    caption.setTranslateX(e.getX());
                                    caption.setTranslateY(e.getY());
                                    caption.setText(String.valueOf(dataTemp.getPieValue()));
                                    caption.setVisible(true);
                            }
                    });
                    dataTemp.getNode().addEventHandler(MouseEvent.MOUSE_EXITED,
                    new EventHandler<MouseEvent>() {
                            @Override public void handle(MouseEvent e) {
                                    caption.setVisible(false);
                            }
                    });
            }
    }

    @Override
    public Node getNodeGraph() {
            return (Node)group;
    }

    @Override
    public void setOptions(OptionsChart optionsChart) {
            //To implemente
    }

    }

感谢@eckig 的回答!

您可以使用 Tooltip 来显示一个值:

for (final PieChart.Data temp : pieChart.getData()) {
    Tooltip tooltip = new Tooltip(String.valueOf(temp.getPieValue()));
    Tooltip.install(temp.getNode(), tooltip);
}