在鼠标单击事件中重置散点图的节点颜色
Reset scatter chart's node color in a mouse-clicked event
我编写了这段创建散点图的代码,并允许我在 click/select 时更改图中节点的颜色。
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);
}
}
问题是,当我 select 另一个点时,前一个点保持蓝色。因此,在更改 selected 点的颜色之前,我需要将所有节点重置为默认颜色。
我试着添加这个:
dataSeries1.getNode().lookup(".chart-symbol").setStyle("-fx-background-color: red");
但我得到:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
您可以做的一件事是遍历数据并更改单击的颜色,并将所有其他设置为 null
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-> {
for(final XYChart.Data<Number,Number> data2 : dataSeries1.getData()) {
if(data == data2)
{
data2.getNode().setStyle("-fx-background-color: blue" );
}
else
{
data2.getNode().setStyle(null);
}
}
});
}
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);
}
}
总结您的要求:
- chart-symbol 的视觉效果 属性 应在用户交互时标记
- 应该只有一个这样的标记符号
听起来像是一种选择机制——开箱即用的图表符号不支持这种机制,应用程序代码必须处理它。任务是
- 跟踪(最后)选定的交易品种
- 保证在任何时候都只选择一个品种
- 根据需要保持 un/selected 的视觉状态
最简单的逻辑实现(前两个项目符号)是保留对当前所选内容的引用并在用户交互时更新它。后者的合适工具是伪类:可以在 css 和 de/activated 中与逻辑一起定义。
代码片段(插入到您的示例中)
// 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 示例,通过 style-sheet f.i.:
加载
.chart-symbol:selected {
-fx-background-color: blue;
}
我编写了这段创建散点图的代码,并允许我在 click/select 时更改图中节点的颜色。
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);
}
}
问题是,当我 select 另一个点时,前一个点保持蓝色。因此,在更改 selected 点的颜色之前,我需要将所有节点重置为默认颜色。 我试着添加这个:
dataSeries1.getNode().lookup(".chart-symbol").setStyle("-fx-background-color: red");
但我得到:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
您可以做的一件事是遍历数据并更改单击的颜色,并将所有其他设置为 null
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-> {
for(final XYChart.Data<Number,Number> data2 : dataSeries1.getData()) {
if(data == data2)
{
data2.getNode().setStyle("-fx-background-color: blue" );
}
else
{
data2.getNode().setStyle(null);
}
}
});
}
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);
}
}
总结您的要求:
- chart-symbol 的视觉效果 属性 应在用户交互时标记
- 应该只有一个这样的标记符号
听起来像是一种选择机制——开箱即用的图表符号不支持这种机制,应用程序代码必须处理它。任务是
- 跟踪(最后)选定的交易品种
- 保证在任何时候都只选择一个品种
- 根据需要保持 un/selected 的视觉状态
最简单的逻辑实现(前两个项目符号)是保留对当前所选内容的引用并在用户交互时更新它。后者的合适工具是伪类:可以在 css 和 de/activated 中与逻辑一起定义。
代码片段(插入到您的示例中)
// 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 示例,通过 style-sheet f.i.:
加载.chart-symbol:selected {
-fx-background-color: blue;
}