javafx - 在鼠标单击事件中重置散点图的节点颜色
问题描述
我制作了这段代码来创建一个散点图,并允许我在单击/选择它时更改图上节点的颜色。
package com.jpc.javafx.charttest;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.ScatterChart;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class CreateChart extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
//-------Create Chart--------------
NumberAxis xAxis = new NumberAxis();
NumberAxis yAxis = new NumberAxis();
XYChart.Series<Number,Number> dataSeries1 = new XYChart.Series();
ScatterChart chart = new ScatterChart(xAxis,yAxis);
dataSeries1.getData().add(new XYChart.Data( 1, 567));
dataSeries1.getData().add(new XYChart.Data( 5, 612));
dataSeries1.getData().add(new XYChart.Data(10, 800));
chart.getData().add(dataSeries1);
//-----Select node and change color -----
for(final XYChart.Data<Number,Number> data : dataSeries1.getData()) {
data.getNode().setOnMouseClicked(e-> {
//dataSeries1.getNode().lookup(".chart-symbol").setStyle("-fx-background-color: red"); that does not work
data.getNode().setStyle("-fx-background-color: blue" );
});
}
VBox vbox = new VBox(chart);
Scene scene = new Scene(vbox, 400, 200);
primaryStage.setScene(scene);
primaryStage.setHeight(300);
primaryStage.setWidth(1200);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
问题是当我选择另一个点时,前一个点保持蓝色。因此,在更改所选点的颜色之前,我需要将所有节点重置为默认颜色。我试图添加这个:
dataSeries1.getNode().lookup(".chart-symbol").setStyle("-fx-background-color: red");
但我得到:
线程“JavaFX 应用程序线程”中的异常 java.lang.NullPointerException
解决方案
总结一下您的要求:
- 图表符号的视觉属性应在用户交互时标记
- 应该只有一个这样的标记符号
听起来像是一种选择机制——开箱即用的图表符号不支持,应用程序代码必须处理它。任务是
- 跟踪(最后)选定的符号
- 保证在任何时候只选择一个符号
- 根据需要保持 un/selected 的视觉状态
最简单的逻辑实现(前两个项目符号)是保留对当前选择的引用并在用户交互时更新它。后者的合适工具是 PseudoClass:可以在 css 中定义并与逻辑一起取消/激活。
代码片段(要插入到您的示例中)
// Pseudo-class
private PseudoClass selected = PseudoClass.getPseudoClass("selected");
// selected logic
private Node selectedSymbol;
protected void setSelectedSymbol(Node symbol) {
if (selectedSymbol != null) {
selectedSymbol.pseudoClassStateChanged(selected, false);
}
selectedSymbol = symbol;
if (selectedSymbol != null) {
selectedSymbol.pseudoClassStateChanged(selected, true);
}
}
// event handler on every symbol
data.getNode().setOnXX(e -> setSelectedSymbol(data.getNode()));
css 示例,通过样式表 fi 加载:
.chart-symbol:selected {
-fx-background-color: blue;
}
推荐阅读
- influxdb - 获取多个标签的最后一个值
- vue.js - vuex:不要在突变之外改变 vuex 存储状态
- java - 将鼠标移出屏幕(向左)使其向下和向右移动
- javascript - nodejs中从客户端到服务器的Ajax调用
- javascript - iframe 元素在 onload 事件后返回未定义?
- powershell - 在字符串数组地址设置不正确的远程端点上使用 Set-DnsClientServerAddress
- autodesk-forge - 在将 Forge Viewer 从 v6* 升级到 v7* 后,AGGREGATE_SELECTION_CHANGED_EVENT 停止发送选择对象
- solidity - 使用solidity向智能合约汇款
- soap - gSOAP:如何为特定服务/模式使用 SOAP 而不是 POST
- java - 如何在 NetBeans 中导入 jar 文件