javafx:PieChart不正确的数据处理MouseEvent

时间:2012-08-08 20:56:27

标签: java javafx-2 pie-chart

昨天我刚刚了解了JavaFX,现在正在测试图形选项。我注意到来自Oracle站点(http://docs.oracle.com/javafx/2/charts/pie-chart.htm)的饼图样本的这种行为,但我添加了更多的数据点和一些悬停效果,使其更加明显。

当您将鼠标悬停在图表上时,MouseEvent并不总是由正确的数据段处理。鼠标光标越接近饼图中心,此效果就越明显。当靠近边缘时,就我所知,行为是准确的。

任何人都可以证实吗?这是一个错误,还是我做错了什么?

尝试移动鼠标,从段的标记边缘开始,向内移动到中心,看看光标下的段是否正确显示。

Screenshot of chart - mouse is where tooltip shows

在玩这张图表时我注意到了其他一些事情 -

  1. 笔画效果(此处为白色短划线)在a上不一致 分割。左边经常看起来被剪裁
  2. 如何更改java中的工具提示页面角?在CSS中它是“.page-corner”
  3. 有吗? 任何方式来改变饼标线的形状,或删除 圆形端点全部在一起?
  4. 编辑:忘了添加代码!

    package piechartsample;
    
    import javafx.application.Application;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.EventHandler;
    import javafx.geometry.Side;
    import javafx.scene.Scene;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    import javafx.scene.chart.*;
    import javafx.scene.control.Label;
    import javafx.scene.control.Tooltip;
    import javafx.scene.effect.Glow;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.shape.StrokeType;
    import javafx.scene.Node;
    
    public class PieChartSample extends Application {
    
        private PieChart.Data selectedData;
        private Tooltip tooltip;
    
        @Override
        public void start(Stage stage) {
    
            ObservableList<PieChart.Data> pieChartData =
                    FXCollections.observableArrayList(
                    new PieChart.Data("Grapefruit", 13),
                    new PieChart.Data("Orange", 25),
                    new PieChart.Data("Plum", 10),
                    new PieChart.Data("Pear", 22),
                    new PieChart.Data("Banana", 10),
                    new PieChart.Data("Peach", 5),
                    new PieChart.Data("Apricot", 1),
                    new PieChart.Data("Pineapple", 20),
                    new PieChart.Data("Passion Fruit", 100),
                    new PieChart.Data("Lychee", 5));
    
            final PieChart chart = new PieChart(pieChartData);
            chart.setTitle("Fruits Graph");
            chart.setLabelLineLength(10);
            chart.setLegendSide(Side.LEFT);
    
            final Label caption = new Label("");
            caption.setTextFill(Color.DARKORANGE);
            caption.setStyle("-fx-font: 24 arial;");
    
            tooltip = new Tooltip("");
    
            tooltip.setStyle("-fx-font: 14 arial;  -fx-font-smoothing-type: lcd;");// -fx-text-fill:black; -fx-background-color: linear-gradient(#e2ecfe, #99bcfd);");
    
    
            for (final PieChart.Data data : chart.getData()) {
                Tooltip.install(data.getNode(),tooltip);
                applyMouseEvents(data);
            }
    
            BorderPane pane = new BorderPane();
            pane.setCenter(chart);
            Scene scene = new Scene(pane);
            stage.setTitle("Fruits");
            stage.setScene(scene);
    //        scene.getStylesheets().add("piechartsample/Chart.css");
            stage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    
        private void applyMouseEvents(final PieChart.Data data) {
    
            final Node node = data.getNode();
    
            node.setOnMouseEntered(new EventHandler<MouseEvent>() {
    
                @Override
                public void handle(MouseEvent arg0) {
                    node.setEffect(new Glow());
                    String styleString = "-fx-border-color: white; -fx-border-width: 3; -fx-border-style: dashed;";
                    node.setStyle(styleString);
                    tooltip.setText(String.valueOf(data.getName() + "\n" + (int)data.getPieValue()) ); 
                }
            });
    
            node.setOnMouseExited(new EventHandler<MouseEvent>() {
    
                @Override
                public void handle(MouseEvent arg0) {
                    node.setEffect(null);
                    node.setStyle("");
                }
            });
    
            node.setOnMouseReleased(new EventHandler<MouseEvent>() {
    
                @Override
                public void handle(MouseEvent mouseEvent) {
                        selectedData = data;
                        System.out.println("Selected data " + selectedData.toString());
                }
            });
        }
    
    }
    

1 个答案:

答案 0 :(得分:1)

  

PieChart MouseEvent的错误拾取行为

对于您的特定实现,在使用JavaFX 2.2时,我没有遇到切片区域的拾取问题。

饼图切片区域的拾取错误似乎是一个已知问题。对于JavaFX 2.2(jdk7u6),问题似乎是partially fixed。有一个outstanding issue与此计划相关的JavaFX 3.0。任何人都可以注册访问权限以查看此答案中链接的jira问题。

此处提供JavaFX 2.2 developer preview


  

如何更改java中的工具提示页面角?

JavaFX css reference guide提供有关工具提示的css结构的信息。这表明子结构具有类.page-corner。要查看JavaFX默认的里海皮肤样式页面角落,您可以查看caspian.css。这个答案中的链接是2.2版本。如果需要,您还可以从jfxrt.jar中为JavaFX安装提取caspian.css。

一旦你有caspian.css,你可以搜索工具提示,看看应用于.page-corner css类的特定样式。这是默认的.page-corner样式=&gt;

.page-corner {
  -fx-padding: 4.5 4.5 4.5 4.5;
  -fx-background-color: linear-gradient( from 0% 0% to 50% 50%, #fcf7b6, #a59c31);
  -fx-shape: "M0,0H9L0,9Z";
  -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 4 , 0.0 , 0 , 0 );
}

要更改默认样式,请使用您对页面角落的特定定义加载您自己的用户css样式表。例如,以下样式类定义会将页面角变为发光的绿色pac-man。

.page-corner {
  -fx-padding: 10;
  -fx-background-color: green;
  -fx-shape: "M30,20 h-15 a15,15 0 1,0 15,-15 z";
  -fx-effect: dropshadow( three-pass-box , derive(green, 40%), 10, 0.0 , 0 , 0 );
}

  

有没有办法改变pie-label-line的形状,或者一起删除圆形端点?

是的,但并非完全直截了当。

看起来,pie-label-line是一个实现的单个Path,它通过以下方式设置:

.chart-pie-label-line {
  -fx-stroke: #aaaaaa;
  -fx-fill: #aaaaaa;
}

要更改路径的形状,您可以在显示图表后对标签行进行查找,并编写一些从中删除球元素的代码;例如(Path) chart.lookup(".chart-pie-label-line")或者您可以继承PieChart并覆盖layoutChartChildren方法。此版本的PieChart source中的第670-6行是生成标签行的行。


  

笔划效果(此处为白色短划线)在细分上不一致。左边经常看起来被剪裁

裁剪是因为您将边框应用于饼图切片节点,并且饼图在内部布局,以便后面添加到图表的项目覆盖更早的项目。添加粗边框时,(绘制的最后一个切片除外)边框将与绘制的下一个饼图切片重叠。您可以通过鼠标输入方法调用node.toFront()来解决此问题。

然而,笔划还存在其他偏移问题,它应该更好地在饼图上对齐。如果笔划宽度设置为1,则它会很好地对齐,如果将其设置为更大的数字(如10)则最终不会对齐。我的猜测是这是边框样式的css处理中的一些错误,并鼓励注册一个帐户并在JavaFX问题跟踪器中记录jira issue


将问题标题中与问题标题无关的其他问题发布为单独的stackoverflow问题可能会更好。