Я провел некоторый поиск, пытаясь заставить эту работу работать, и причина, по которой toFront не работает, поскольку Javadoc заявляет
Перемещает этот узел к передней части его родственных узлов с точки зрения z-порядок.Это достигается путем перемещения этого узла на последнюю позицию в содержимом родительского объекта ObservableList. Эта функция не действует, если этот узел не является частью группы.
Так что я не мог заставить это работать в любом смысле.Это единственное решение, которое я мог придумать, заключающееся в определении ширины / высоты метки / 2 и смещении метки, если она на оси X или Y, чтобы вы могли ее видеть
Я не внес никаких измененийв Main, кроме жесткого кодирования значения тестирования и удаления вызовов toFront
public class Main extends Application {
@Override
public void start(Stage stage) throws Exception{
// Random chart
// Defining the Axis
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
// Creating the chart
LineChart<Number, Number> lineChart = new LineChart<>(xAxis, yAxis);
// Preparing the series
XYChart.Series series = new XYChart.Series();
series.setName("Chart");
boolean firstRun = true;//First point at 0,0 to test
for (double x = 0; x <= 10; x++) {
double y;
if(firstRun) {
y = 0.0;
firstRun = false;
}else
y = Math.random() * 100;
XYChart.Data chartData;
chartData = new XYChart.Data<>(x, y);
chartData.setNode(new ShowCoordinatesNode(x, y));
series.getData().add(chartData);
}
// Adding series to chart
lineChart.getData().add(series);
Scene scene = new Scene(lineChart, 800, 600);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) { launch(args); }
}
Здесь я добавил 2 оператора If для перевода метки, если он находится на одной из осей
public class ShowCoordinatesNode extends StackPane {
public ShowCoordinatesNode(double x, double y) {
final Label label = createDataThresholdLabel(x, y);
setOnMouseEntered(mouseEvent -> {
setScaleX(1);
setScaleY(1);
getChildren().setAll(label);
if(x == 0.0) {
applyCss();
layout();
label.setTranslateX(label.getWidth()/2);
}
if(y == 0.0){
applyCss();
layout();
label.setTranslateY(-label.getHeight()/2);
}
setCursor(Cursor.NONE);
});
setOnMouseExited(mouseEvent -> {
getChildren().clear();
setCursor(Cursor.CROSSHAIR);
});
}
private Label createDataThresholdLabel(double x, double y) {
DecimalFormat df = new DecimalFormat("0.##");
final Label label = new Label("(" + df.format(x) + "; " + df.format(y) + ")");
label.getStyleClass().addAll("default-color0", "chart-line-symbol", "chart-series-line");
label.setStyle("-fx-font-size: 10; -fx-font-weight: bold;");
label.setMinSize(Label.USE_PREF_SIZE, Label.USE_PREF_SIZE);
label.setId("show-coord-label");
return label;
}
}
Я использую applyCSS (), чтобы вычислить размер метки перед ее добавлением в окно. JavaDoc сообщает:
Если необходимо, примените стили к этому Узлу и его дочерним элементам, если таковые имеются.Этот метод обычно не нужно вызывать напрямую, но его можно использовать вместе с Parent.layout () для определения размера узла перед следующим импульсом или если сцена не находится в рабочей области.