Text javafx2.x:如何在图表上书写文本?
通过鼠标左键单击图表,我想通过创建文本区域矩形来编写文本,以便能够调整大小和移动 非常感谢您的帮助 编辑:您好,非常感谢您的回复 我尝试了你的代码,它编译并绘制了带注释的面积图,非常棒的工作 我现在需要更改您的代码,以便在鼠标左键单击时能够使用键盘键入,而不是现在打印注释 下面是您的完整代码Text javafx2.x:如何在图表上书写文本?,text,javafx-2,Text,Javafx 2,通过鼠标左键单击图表,我想通过创建文本区域矩形来编写文本,以便能够调整大小和移动 非常感谢您的帮助 编辑:您好,非常感谢您的回复 我尝试了你的代码,它编译并绘制了带注释的面积图,非常棒的工作 我现在需要更改您的代码,以便在鼠标左键单击时能够使用键盘键入,而不是现在打印注释 下面是您的完整代码 import javafx.application.Application; import javafx.beans.InvalidationListener; import javafx.beans.Ob
import javafx.application.Application;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.Axis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.Label;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
/**
*
* @author sarcan
*/
public class SampleApp extends Application {
public class SampleChart extends AreaChart<Number, Number> {
public SampleChart() {
super(new NumberAxis(), new NumberAxis());
getXAxis().setLabel("X");
getYAxis().setLabel("Y");
final Series<Number, Number> data = new Series<Number, Number>();
data.setName("Dummy data");
data.getData().addAll(
new Data<Number, Number>(0,4),
new Data<Number, Number>(1,5),
new Data<Number, Number>(2,6),
new Data<Number, Number>(3,5),
new Data<Number, Number>(4,5),
new Data<Number, Number>(5,7),
new Data<Number, Number>(6,8),
new Data<Number, Number>(7,9),
new Data<Number, Number>(8,7)
);
getData().add(data);
}
}
public class ChartAnnotationNode {
private final Node _node;
private double _x;
private double _y;
public ChartAnnotationNode(final Node node, final double x, final double y) {
_node = node;
_x = x;
_y = y;
}
public Node getNode() {
return _node;
}
public double getX() {
return _x;
}
public double getY() {
return _y;
}
public void setX(final double x) {
_x = x;
}
public void setY(final double y) {
_y = y;
}
}
public class ChartAnnotationOverlay extends Pane {
private ObservableList<ChartAnnotationNode> _annotationNodes;
private XYChart<Number, Number> _chart;
public ChartAnnotationOverlay(final XYChart<Number, Number> chart) {
_chart = chart;
/* Create a list to hold your annotations */
_annotationNodes = FXCollections.observableArrayList();
/* This will be our update listener, to be invoked whenever the chart changes or annotations are added */
final InvalidationListener listener = new InvalidationListener() {
@Override
public void invalidated(final Observable observable) {
update();
}
};
_chart.needsLayoutProperty().addListener(listener);
_annotationNodes.addListener(listener);
/* Add new annotations by shift-clicking */
setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(final MouseEvent mouseEvent) {
if (mouseEvent.getButton() == MouseButton.PRIMARY && mouseEvent.isShiftDown())
addAnnotation(mouseEvent.getX(), mouseEvent.getY());
}
});
}
/**
* Invoked whenever the chart changes or annotations are added. This basically does a relayout of the annotation nodes.
*/
private void update(){
getChildren().clear();
final Axis<Number> xAxis = _chart.getXAxis();
final Axis<Number> yAxis = _chart.getYAxis();
/* For each annotation, add a circle indicating the position and the custom node right next to it */
for (ChartAnnotationNode annotation : _annotationNodes) {
final double x = xAxis.localToParent(xAxis.getDisplayPosition(annotation.getX()), 0).getX() + _chart.getPadding().getLeft();
final double y = yAxis.localToParent(0,yAxis.getDisplayPosition(annotation.getY())).getY() + _chart.getPadding().getTop();
final Circle indicator = new Circle(3);
indicator.setStroke(Color.BLUEVIOLET);
indicator.setCenterX(x);
indicator.setCenterY(y);
getChildren().add(indicator);
final Node node = annotation.getNode();
getChildren().add(node);
node.relocate(x + 10, y - node.prefHeight(Integer.MAX_VALUE) / 2);
node.autosize();
}
}
/**
* Add a new annotation for the given display coordinate.
*/
private void addAnnotation(final double displayX, final double displayY){
final Axis<Number> xAxis = _chart.getXAxis();
final Axis<Number> yAxis = _chart.getYAxis();
final double x = (xAxis.getValueForDisplay(xAxis.parentToLocal(displayX, 0).getX() - _chart.getPadding().getLeft())).doubleValue();
final double y = (yAxis.getValueForDisplay(yAxis.parentToLocal(0, displayY).getY() - _chart.getPadding().getTop())).doubleValue();
if (xAxis.isValueOnAxis(x) && yAxis.isValueOnAxis(y))
_annotationNodes.add(new ChartAnnotationNode(new Label("Annotation "+System.currentTimeMillis()), x, y));
}
}
@Override
public void start(final Stage stage) throws Exception {
final SampleChart chart = new SampleChart();
final ChartAnnotationOverlay overlay = new ChartAnnotationOverlay(chart);
final StackPane stackPane = new StackPane();
stackPane.getChildren().addAll(chart, overlay);
final Scene scene = new Scene(stackPane);
stage.setScene(scene);
stage.setWidth(800);
stage.setHeight(600);
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
导入javafx.application.application;
导入javafx.beans.InvalizationListener;
导入javafx.beans.Observable;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.event.EventHandler;
导入javafx.scene.Node;
导入javafx.scene.scene;
导入javafx.scene.chart.AreaChart;
导入javafx.scene.chart.Axis;
导入javafx.scene.chart.NumberAxis;
导入javafx.scene.chart.XYChart;
导入javafx.scene.chart.XYChart.Data;
导入javafx.scene.chart.XYChart.Series;
导入javafx.scene.control.Label;
导入javafx.scene.input.MouseButton;
导入javafx.scene.input.MouseEvent;
导入javafx.scene.layout.Pane;
导入javafx.scene.layout.StackPane;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.Circle;
导入javafx.stage.stage;
/**
*
*@作者sarcan
*/
公共类SampleApp扩展了应用程序{
公共类样本图扩展了区域图{
公共样本图表(){
super(newnumberaxis(),newnumberaxis());
getXAxis().setLabel(“X”);
getYAxis().setLabel(“Y”);
最终系列数据=新系列();
data.setName(“虚拟数据”);
data.getData().addAll(
新数据(0,4),
新数据(1,5),
新数据(2,6),
新数据(3,5),
新数据(4,5),
新数据(5,7),
新数据(6,8),
新数据(7,9),
新数据(8,7)
);
getData()。添加(数据);
}
}
公共类ChartAnnotationNode{
私有最终节点_节点;
私人双x;
私人双人房;
公共图表注释节点(最终节点节点、最终双x、最终双y){
_节点=节点;
_x=x;
_y=y;
}
公共节点getNode(){
返回_节点;
}
公共双getX(){
返回x;
}
公共双盖{
返回y;
}
公共无效集合x(最终双x){
_x=x;
}
公共无效setY(最终双y){
_y=y;
}
}
公共类ChartAnnotationOverlay扩展窗格{
私有ObservableList注释节点;
私有XYChart \u图;
公共图表注释覆盖(最终XYChart图表){
_图表=图表;
/*创建一个列表来保存注释*/
_annotationNodes=FXCollections.observableArrayList();
/*这将是我们的更新侦听器,在添加图表更改或注释时调用*/
final InvalizationListener listener=新的InvalizationListener(){
@凌驾
公共无效(最终可观测){
更新();
}
};
_chart.needsLayoutProperty().addListener(listener);
_annotationNodes.addListener(listener);
/*通过按住shift键并单击添加新批注*/
setOnMouseClicked(新事件处理程序(){
@凌驾
公共无效句柄(最终MouseEvent MouseEvent){
if(mouseEvent.getButton()==MouseButton.PRIMARY&&mouseEvent.isShiftDown())
addAnnotation(mouseEvent.getX(),mouseEvent.getY());
}
});
}
/**
*每当图表更改或添加注释时调用。这基本上会重新显示注释节点。
*/
私有void更新(){
getChildren().clear();
最终轴xAxis=_chart.getXAxis();
最终轴yAxis=_chart.getYAxis();
/*对于每个注释,添加一个圆圈,指示位置及其旁边的自定义节点*/
对于(图表注释节点注释:_注释节点){
final double x=xAxis.localToParent(xAxis.getDisplayPosition(annotation.getX()),0.getX()+_chart.getPadding().getLeft();
final double y=yAxis.localToParent(0,yAxis.getDisplayPosition(annotation.getY()).getY()+_chart.getPadding().getTop();
最终循环指示器=新循环(3);
指示器。设定行程(颜色为蓝紫色);
指示器。setCenterX(x);
指示器。设置中心y(y);
getChildren().add(指示符);
最终节点=annotation.getNode();
getChildren().add(节点);
节点重新定位(x+10,y-节点预高度(整数最大值)/2);
node.autosize();
}
}
/**
*为给定的显示坐标添加新注释。
*/
私有void addAnnotation(最终双显示X,最终双显示Y){
最终轴xAxis=_chart.getXAxis();
最终轴yAxis=_chart.getYAxis();
最终的双精度x=(xAxis.getValueForDisplay(xAxis.parentToLocal(displayX,0.getX()-_chart.getPadding().getLeft()).doubleValue();
最终双y=(yAxis.getValueForDisplay(yAxis.parentToLocal(0,display).getY()-\u chart.getPadding().getTop()).doubleValue();
if(x轴isValueOnAxis(x)和&yAxis.isValueOnAxis(y))
_添加(新图表AnnotationNode(新标签(“Annotation”+System.currentTimeMillis()),x,y));
}
}
@凌驾
public void start(final Stage)引发异常{
最终样本图表=新样本图表();
最终ChartAnnotationOverlay=新的ChartAnnotationOverlay(图表);
最终StackPane StackPane=新StackPane();
stackPane.getChildren().addAll(图表、覆盖);
最终场景=新场景(stackPane);
舞台场景;
舞台布景宽度(800);
舞台设置高度(600);
stage.show();
}
公共静态void main(字符串[]args){
应用程序启动(args);
}
}
1)我首先将图表放在堆栈窗格中。在图表的顶部,我会放置一个锚定窗格,鼠标单击后,该窗格将保存文本字段
2) 当用户单击图表时,我会使用图表的轴来确定单击是否在内部
public class SampleChart extends AreaChart<Number, Number> {
public SampleChart() {
super(new NumberAxis(), new NumberAxis());
getXAxis().setLabel("X");
getYAxis().setLabel("Y");
final Series<Number, Number> data = new Series<Number, Number>();
data.setName("Dummy data");
data.getData().addAll(
new Data<Number, Number>(0,4),
new Data<Number, Number>(1,5),
new Data<Number, Number>(2,6),
new Data<Number, Number>(3,5),
new Data<Number, Number>(4,5),
new Data<Number, Number>(5,7),
new Data<Number, Number>(6,8),
new Data<Number, Number>(7,9),
new Data<Number, Number>(8,7)
);
getData().add(data);
}
}
public class ChartAnnotationNode {
private final Node _node;
private double _x;
private double _y;
public ChartAnnotationNode(final Node node, final double x, final double y) {
_node = node;
_x = x;
_y = y;
}
public Node getNode() {
return _node;
}
public double getX() {
return _x;
}
public double getY() {
return _y;
}
public void setX(final double x) {
_x = x;
}
public void setY(final double y) {
_y = y;
}
}
public class ChartAnnotationOverlay extends Pane {
private ObservableList<ChartAnnotationNode> _annotationNodes;
private XYChart<Number, Number> _chart;
public ChartAnnotationOverlay(final XYChart<Number, Number> chart) {
_chart = chart;
/* Create a list to hold your annotations */
_annotationNodes = FXCollections.observableArrayList();
/* This will be our update listener, to be invoked whenever the chart changes or annotations are added */
final InvalidationListener listener = new InvalidationListener() {
@Override
public void invalidated(final Observable observable) {
update();
}
};
_chart.needsLayoutProperty().addListener(listener);
_annotationNodes.addListener(listener);
/* Add new annotations by shift-clicking */
setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(final MouseEvent mouseEvent) {
if (mouseEvent.getButton() == MouseButton.PRIMARY && mouseEvent.isShiftDown())
addAnnotation(mouseEvent.getX(), mouseEvent.getY());
}
});
}
/**
* Invoked whenever the chart changes or annotations are added. This basically does a relayout of the annotation nodes.
*/
private void update(){
getChildren().clear();
final Axis<Number> xAxis = _chart.getXAxis();
final Axis<Number> yAxis = _chart.getYAxis();
/* For each annotation, add a circle indicating the position and the custom node right next to it */
for (ChartAnnotationNode annotation : _annotationNodes) {
final double x = xAxis.localToParent(xAxis.getDisplayPosition(annotation.getX()), 0).getX() + _chart.getPadding().getLeft();
final double y = yAxis.localToParent(0,yAxis.getDisplayPosition(annotation.getY())).getY() + _chart.getPadding().getTop();
final Circle indicator = new Circle(3);
indicator.setStroke(Color.BLUEVIOLET);
indicator.setCenterX(x);
indicator.setCenterY(y);
getChildren().add(indicator);
final Node node = annotation.getNode();
getChildren().add(node);
node.relocate(x + 10, y - node.prefHeight(Integer.MAX_VALUE) / 2);
node.autosize();
}
}
/**
* Add a new annotation for the given display coordinate.
*/
private void addAnnotation(final double displayX, final double displayY){
final Axis<Number> xAxis = _chart.getXAxis();
final Axis<Number> yAxis = _chart.getYAxis();
final double x = (xAxis.getValueForDisplay(xAxis.parentToLocal(displayX, 0).getX() - _chart.getPadding().getLeft())).doubleValue();
final double y = (yAxis.getValueForDisplay(yAxis.parentToLocal(0, displayY).getY() - _chart.getPadding().getTop())).doubleValue();
if (xAxis.isValueOnAxis(x) && yAxis.isValueOnAxis(y))
_annotationNodes.add(new ChartAnnotationNode(new Label("Annotation "+System.currentTimeMillis()), x, y));
}
}
public class SampleApp extends Application {
@Override
public void start(final Stage stage) throws Exception {
final SampleChart chart = new SampleChart();
final ChartAnnotationOverlay overlay = new ChartAnnotationOverlay(chart);
final StackPane stackPane = new StackPane();
stackPane.getChildren().addAll(chart, overlay);
final Scene scene = new Scene(stackPane);
stage.setScene(scene);
stage.setWidth(800);
stage.setHeight(600);
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}