基本上,当我将鼠标悬停在其中一个峰值上时,我想显示工具提示中的一些额外信息。
但是,我无法猜测如何在监视器上获取峰值位置(因为工具提示要求显示器的绝对坐标)
这是我目前的代码
//dateNumberData is the peak
Tooltip tooltip = new Tooltip();
//Here i just edit tooltip info
dateNumberData.getNode().setOnMouseEntered(event -> {
tooltip.show(dateNumberData.getNode(),
dateNumberData.getNode().localToScreen(dateNumberData.getNode().getLayoutX(), 0).getX(),
dateNumberData.getNode().localToScreen(0, dateNumberData.getNode().getLayoutY()).getY());
});
dateNumberData.getNode().setOnMouseExited(event -> tooltip.hide());
但工具提示到处都是。如果我使用dateNumberData.getNode().getParent().localToScreen()
工具提示,则根本不会出现(但tooltip.getX()会返回一个正确的坐标。至少它会显示这些坐标)
答案 0 :(得分:0)
layoutX()
和layoutY()
属性不适合在此处使用。那些可能是父节点中的节点的坐标,但是你不知道通过设置节点来定位节点:它可能使用翻译或其他布局机制。而是使用getBoundsInLocal()
然后转换边界。
在工具提示中添加一个小偏移量也是一个好主意:这不仅看起来更好,而且还可以防止工具提示模糊节点,这意味着您可以触发鼠标退出,并最终进入重复循环。
dateNumberData.getNode().setOnMouseEntered(event -> {
Bounds bounds = dateNumberData.getNode().localToScreen(dateNumberData.getNode().getBoundsInLocal());
tooltip.show(dateNumberData.getNode(),
bounds.getMaxX()+15,
bounds.getMaxY()+5);
});
这是一个SSCCE:
import java.util.Random;
import javafx.application.Application;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class LineChartWithTooltip extends Application {
@Override
public void start(Stage primaryStage) {
LineChart<Number, Number> chart = new LineChart<>(new NumberAxis(), new NumberAxis());
Series<Number, Number> series = new Series<>();
series.setName("Data");
Random rng = new Random();
for (int i = 0 ; i <= 10; i++) {
series.getData().add(new Data<>(i, rng.nextDouble()));
}
chart.getData().add(series);
Tooltip tooltip = new Tooltip();
for (Data<Number, Number> d : series.getData()) {
d.getNode().setOnMouseEntered(event -> {
tooltip.setText(String.format("[%d, %.3f]", d.getXValue().intValue(), d.getYValue().doubleValue()));
Bounds nodeBounds = d.getNode().getBoundsInLocal();
Bounds nodeBoundsInScreen = d.getNode().localToScreen(nodeBounds);
tooltip.show(d.getNode(),
nodeBoundsInScreen.getMaxX()+15,
nodeBoundsInScreen.getMaxY()+5);
});
d.getNode().setOnMouseExited(event -> tooltip.hide());
}
primaryStage.setScene(new Scene(new BorderPane(chart), 600, 600));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}