我最喜欢的JavaFX 2功能之一是它在javafx.scene.chart包中提供的标准图表。 该软件包提供了几种不同类型的现成图表。 除了其中之一( PieChart )以外,所有其他都是“ 2轴图”( XYChart的特定实现)。 在本文中,我将介绍XYChart这些专业之间的共性。 在此过程中,我将介绍一些方便的Java 7功能。

接下来显示javafx.scene.chart包中关键图类型的UML类图。 注意AreaChart , StackedAreaChart , BarChart , StackedBarChart , BubbleChart , LineChart和ScatterChart都扩展了XYChart

正如上面的UML图(使用JDeveloper生成)所示, PieChart直接扩展Chart ,而所有其他图表类型都扩展XYChart 。 因为除PieChart之外的所有其他图表类型都扩展了XYChart ,所以它们共享一些共同的功能。 例如,它们都是带有水平('x')轴和垂直('y')轴的2轴图表。 它们通常允许为所有XY图表以相同的格式(数据结构)指定数据。 这篇文章的其余部分演示了能够对大多数XYChart使用相同的数据。

图表的主要用途是显示数据,因此下一个代码清单指示从Oracle数据库中的“ hr ” 样本架构中检索数据。 请注意,JDBC_URL,USERNAME,PASSWORD和AVG_SALARIES_PER_DEPARTMENT_QUERY是在JDBC连接和查询中使用的常量字符串。

getAverageDepartmentsSalaries()

/*** Provide average salary per department name.* * @return Map of department names to average salary per department.*/
public Map<String, Double> getAverageDepartmentsSalaries()
{final Map<String, Double> averageSalaryPerDepartment = new HashMap<>();try (final Connection connection = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD);final Statement statement = connection.createStatement();final ResultSet rs = statement.executeQuery(AVG_SALARIES_PER_DEPARTMENT_QUERY)){while (rs.next()){final String departmentName = rs.getString(COLUMN_DEPARTMENT_NAME);final Double salaryAverage = rs.getDouble(ALIAS_AVERAGE_SALARY);averageSalaryPerDepartment.put(departmentName, salaryAverage);}}catch (SQLException sqlEx){LOGGER.log(Level.SEVERE,'Unable to get average salaries per department - {0}', sqlEx.toString());}return averageSalaryPerDepartment;
}

上面的Java代码段使用JDBC检索数据,以将部门名称字符串Map为每个部门中雇员的平均工资。 此代码中使用了几个方便的Java 7功能。 一个小的功能是与局部变量averageSalaryPerDepartment的声明一起使用的diamond运算符的推断通用参数化类型(第8行)。 这是语法糖的一小部分,但确实使代码更简洁。

Java 7的一项更重要的功能是使用try-with-resources语句来处理Connection , Statement和ResultSet资源(第9-11行)。 与以前使用JDBC相比,即使面对异常,这也是处理这些资源打开和关闭的一种更好的方法。 try-with-resources语句上的Java Tutorials页面广告该语句“确保在语句末尾关闭每个资源”,并且确保每个资源都将被“关闭”,而不管try语句是正常完成还是突然完成。 该页面还指出,与上述代码一样,在同一语句中指定了多个资源时,“资源的close方法将按其创建的相反顺序进行调用。”

从数据库检索的数据可以放入适当的数据结构中,以支持大多数XYCharts的使用。 这在下一个方法中显示。

ChartMaker.createXyChartDataForAverageDepartmentSalary(地图)

/*** Create XYChart Data representing average salary per department name.* * @param newAverageSalariesPerDepartment Map of department name (keys) to*    average salary for each department (values).* @return XYChart Data representing average salary per department.*/
public static ObservableList<XYChart.Series<String, Double>> createXyChartDataForAverageDepartmentSalary(final Map<String, Double> newAverageSalariesPerDepartment)
{final Series<String, Double> series = new Series<>();series.setName('Departments');for (final Map.Entry<String, Double> entry : newAverageSalariesPerDepartment.entrySet()){series.getData().add(new XYChart.Data<>(entry.getKey(), entry.getValue()));}final ObservableList<XYChart.Series<String, Double>> chartData =FXCollections.observableArrayList();chartData.add(series);return chartData;
}

刚刚显示的方法将检索到的数据放置在几乎所有基于XYChart的图表都可以使用的数据结构中。 现在,将检索到的数据打包到JavaFX可观察的集合中,就可以轻松生成图表。 下一个代码片段显示了用于生成多个基于XYChart的图表(面积,条形图,气泡图,折线图和散点图)的方法。 请注意它们都是多么相似,以及如何使用由相同方法提供的相同数据。 StackedBar和StackedArea图表也可以使用类似的数据,但此处未显示,因为它们对于本示例中使用的单个数据系列没有意义。

除BubbleChart和堆积图表外的生成XYCharts的方法

private XYChart<String, Double> generateAreaChart(final Axis<String> xAxis, final Axis<Double> yAxis)
{final AreaChart<String, Double> areaChart =new AreaChart<>(xAxis, yAxis,ChartMaker.createXyChartDataForAverageDepartmentSalary(this.databaseAccess.getAverageDepartmentsSalaries()));return areaChart;
}private XYChart<String, Double> generateBarChart(final Axis<String> xAxis, final Axis<Double> yAxis)
{final BarChart<String, Double> barChart =new BarChart<>(xAxis, yAxis,ChartMaker.createXyChartDataForAverageDepartmentSalary(this.databaseAccess.getAverageDepartmentsSalaries()));return barChart;
}private XYChart<Number, Number> generateBubbleChart(final Axis<String> xAxis, final Axis<Double> yAxis)
{final Axis<Number> deptIdXAxis = new NumberAxis();deptIdXAxis.setLabel('Department ID');final BubbleChart<Number, Number> bubbleChart =new BubbleChart(deptIdXAxis, yAxis,ChartMaker.createXyChartDataForAverageDepartmentSalaryById(this.databaseAccess.getAverageDepartmentsSalariesById()));return bubbleChart;
}private XYChart<String, Double> generateLineChart(final Axis<String> xAxis, final Axis<Double> yAxis)
{final LineChart<String, Double> lineChart =new LineChart<>(xAxis, yAxis,ChartMaker.createXyChartDataForAverageDepartmentSalary(this.databaseAccess.getAverageDepartmentsSalaries()));return lineChart;
}private XYChart<String, Double> generateScatterChart(final Axis<String> xAxis, final Axis<Double> yAxis)
{final ScatterChart<String, Double> scatterChart =new ScatterChart<>(xAxis, yAxis,ChartMaker.createXyChartDataForAverageDepartmentSalary(this.databaseAccess.getAverageDepartmentsSalaries()));return scatterChart;
}

这些方法是如此相似,以至于我实际上可以使用方法句柄(或更传统的反射API)来反射性地调用适当的图表构造函数,而不是使用单独的方法。 但是,我在2月的2013年RMOUG培训日演讲中使用了这些功能,因此希望保留图表专用的构造函数,以使它们对观众更清晰。

XYChart类型的常规处理的一个例外是BubbleChart的处理。 此图表的x轴需要数字类型,因此上面提供的基于字符串(部门名称)的x轴数据将不起作用。 另一种方法(此处未显示)提供了一个查询,该查询按部门ID(长)而不是部门名称返回平均工资。 接下来显示了稍有不同的generateBubbleChart方法。

generateBubbleChart(Axis,Axis)

private XYChart<Number, Number> generateBubbleChart(final Axis<String> xAxis, final Axis<Double> yAxis){final Axis<Number> deptIdXAxis = new NumberAxis();deptIdXAxis.setLabel('Department ID');final BubbleChart<Number, Number> bubbleChart =new BubbleChart(deptIdXAxis, yAxis,ChartMaker.createXyChartDataForAverageDepartmentSalaryById(this.databaseAccess.getAverageDepartmentsSalariesById()));return bubbleChart;}

可以编写代码来直接调用每种不同的图表生成方法,但这为使用Java 7的方法句柄提供了一个很好的机会。 下一个代码片段显示了此操作。 该代码不仅演示了方法句柄,而且还使用了Java 7的多捕获异常处理机制(第77行)。

/*** Generate JavaFX XYChart-based chart.* * @param chartChoice Choice of chart to be generated.* @return JavaFX XYChart-based chart; may be null.* @throws IllegalArgumentException Thrown if the provided parameter is null.*/
private XYChart<String, Double> generateChart(final ChartTypes chartChoice)
{XYChart<String, Double> chart = null;final Axis<String> xAxis = new CategoryAxis();xAxis.setLabel('Department Name');final Axis<? extends Number> yAxis = new NumberAxis();yAxis.setLabel('Average Salary');if (chartChoice == null){throw new IllegalArgumentException('Provided chart type was null; chart type must be specified.');}else if (!chartChoice.isXyChart()){LOGGER.log(Level.INFO,'Chart Choice {0} {1} an XYChart.',new Object[]{chartChoice.name(), chartChoice.isXyChart() ? 'IS' : 'is NOT'});}final MethodHandle methodHandle = buildAppropriateMethodHandle(chartChoice);try{chart =methodHandle != null? (XYChart<String, Double>) methodHandle.invokeExact(this, xAxis, yAxis): null;chart.setTitle('Average Department Salaries');}catch (WrongMethodTypeException wmtEx){LOGGER.log(Level.SEVERE,'Unable to invoke method because it is wrong type - {0}',wmtEx.toString());}catch (Throwable throwable){LOGGER.log(Level.SEVERE,'Underlying method threw a Throwable - {0}',throwable.toString());}return chart;
}/*** Build a MethodHandle for calling the appropriate chart generation method* based on the provided ChartTypes choice of chart.* * @param chartChoice ChartTypes instance indicating which type of chart*    is to be generated so that an appropriately named method can be invoked*    for generation of that chart.* @return MethodHandle for invoking chart generation.*/
private MethodHandle buildAppropriateMethodHandle(final ChartTypes chartChoice)
{MethodHandle methodHandle = null;final MethodType methodDescription =MethodType.methodType(XYChart.class, Axis.class, Axis.class);final String methodName = 'generate' + chartChoice.getChartTypeName() + 'Chart';try{methodHandle =MethodHandles.lookup().findVirtual(this.getClass(), methodName, methodDescription);}catch (NoSuchMethodException | IllegalAccessException exception){LOGGER.log(Level.SEVERE,'Unable to acquire MethodHandle to method {0} - {1}',new Object[]{methodName, exception.toString()});}return methodHandle;
}

随后的一系列图像显示了由JavaFX渲染时这些XY图表的显示方式。

面积图

条形图

气泡图

折线图

散点图

如上所述,方法句柄可能已被用来进一步减少代码,因为用于生成每个XYChart各个方法不是绝对必要的,并且可以根据所需的图表类型进行反射式调用。 还值得强调的是,如果x轴数据是数字的,则所有XYChart类型(包括气泡图)的代码都是相同的(并且可以被反射地调用)。

JavaFX使生成代表所提供数据的吸引人的图表变得容易。 Java 7功能通过使代码更简洁,更具表现力,并允许在适当的情况下轻松应用反射,使此操作变得更加容易。

参考:来自JCG合作伙伴 Dustin Marx的JavaFX 2 XYCharts和Java 7功能,来自Inspired by Actual Events博客。

翻译自: https://www.javacodegeeks.com/2013/01/javafx-2-xycharts-and-java-7-features.html

JavaFX 2 XYCharts和Java 7功能相关推荐

  1. java 和javafx_JavaFX 2 XYCharts和Java 7功能

    java 和javafx 我最喜欢的JavaFX 2功能之一是它在javafx.scene.chart包中提供的标准图表. 该软件包提供了几种不同类型的现成图表. 除其中之一( PieChart )外 ...

  2. JAVAFX 实现QQ列表以及闪烁功能

    JAVAFX 实现QQ列表以及闪烁功能 package ztf.start;import javafx.application.Application; import javafx.collectio ...

  3. PHP和Java的联系,PHP和Java的功能

    PHP和Java的功能 PHP和Java PHP功能的另外一个高招是其调用已有Java对象的方法的能力,这种功能可以让你把PHP集成进已有的基于Java的应用程序.如果你正在你的工作场合推广PHP , ...

  4. Java堆栈功能_【ThinkingInJava】35、用java实现堆栈功能

    /** * 书本:<Thinking In Java> * 功能:用java实现堆栈功能 * 文件:LinkedStack.java * 时间:2015年4月17日14:23:34 * 作 ...

  5. android java 8_四个库,让你在 Android 中启用 Java 8 功能

    Java 8 的推出引入很多革命性变化,加入了函数式编程的特征,使基于行为的编程成为可能,同时简化了各种设计模式的实现方式,是 Java 有史以来最重要的更新. 自 Android N 之后,由于 J ...

  6. java 新功能_Java 14的新功能

    java 新功能 2020年3月17日,Oracle发布了名为Java 14的Java新版本,其中包括许多新功能,工具,安全性,调试和更新的文档方面的改进. 但是,Oracle还向您提供Java的较旧 ...

  7. java多功能钟_Java 11将包含更多功能

    java多功能钟 Java 11即将发布的功能是什么?它与Java 9和10有何不同? Java 10可能是新手,但现在该谈论Java 11了.Oracle迈向更快的发布周期意味着更多的特性和功能以比 ...

  8. java:退出功能_Java 8:功能VS传统

    java:退出功能 业务逻辑是相同的: 给定一个由访问次数/时间组成的String表达式,例如:" 1 / 24h,1..3 / 3h,5 / *" 然后,结果应为以下字符串列表: ...

  9. java 鲜为人知的知识点_鲜为人知的Java 8功能:广义目标类型推断

    java 鲜为人知的知识点 遍历Java 8的功能列表 , 广义目标类型推断使我震惊,因为它是一个特别有趣,鲜为人知的瑰宝. 看起来Java语言设计人员将减轻过去使用泛型(Java 5-7)时遇到的某 ...

最新文章

  1. 暴力探测蓝牙设备工具redfang
  2. 翻译: TypeScript 1.8 Beta 发布
  3. 机器学习笔记: attention
  4. EOS账户系统(4)账户权限分级
  5. 工业以太网交换机选机攻略
  6. 十大经典排序算法(动态演示+代码)
  7. WampServer无法直接打开myprojects的解决方法
  8. .Net 转战 Android 4.4 日常笔记(1)--工具及环境搭建
  9. 回溯法——设计一个算法在1、2、3... 9(顺序不能变)数字之间插入+ 或 - 或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性和全排列
  10. python手册中文版-Python中文文档
  11. 征途猎魔mysql数据库_字典列表的拓展理解
  12. QQ语音老是连接服务器超时,手机QQ提示连接超时请检查网络设置解决办法
  13. 一种兼顾速度和效果的对比度增强算法——CONTRAST ENHANCEMENT BASED ON LAYERED DIFFERENCE REPRESENTATION
  14. 方舟生存进化怎么自建服务器?方舟生存进化自建服务器教程
  15. 蓝牙音乐之A2DP音频流
  16. 计算机win2000如何连接wifi,台式电脑windows7怎么连接wifi
  17. 手机开热点如何查看接入热点的所有ip
  18. 会声会影找不到MSVCP100.dll、MSVCR100.dll时怎么办?(其他软件也适合使用)
  19. Gentoo USE参数清单中文详解{转}
  20. 让 Vivado有Zybo Board的配置文件

热门文章

  1. java语言中的访问权限控制符有哪些,18.Java的访问控制符
  2. centos8上安装nginx
  3. LNCS用户写作指南【 Springer Computer Science Proceedings 】
  4. MySQL日志:binlog、事务日志(redo、undo)
  5. java开发展望怎么写_Java开发趋势:2019年展望
  6. junit junit_JSON的JUnit Hamcrest Matcher
  7. gatling的环境配置_将Gatling集成到Gradle构建中–了解SourceSet和配置
  8. 线程同步 线程安全_同步装饰器来替换线程安全类
  9. 从事java编程技能要求_5道Java视频课程,提高您的编程技能
  10. java jsp学习指南_JSP教程–最终指南