我正在尝试创建一个可滚动的图表,其中Y轴保持在视图中,无论滚动条中的光标位置如何(默认情况下,因为Y轴信息位于视图的末尾,您只能看到它滚动到足以看到结束后)
这是我想要完成的一个例子:
请注意,即使滚动条位置处于中间位置,Y轴文本(价格)仍然在视图中
我环顾网页,只能找到一个类似的例子,但它似乎不适用于scrollPane中的折线图。
Always visible when scrolled anchored Node in Java FX 2.0?
上述内容适用于Circle对象,但会导致更改为折线图 在“例外:无法设置绑定值”,因为它似乎在滚动窗格内使用折线图时自动调用设置布局
public class FancyScrollPane extends Application {
private LineChart<String, Number> qChart;
@Override
public void start(Stage primaryStage) {
ScrollPane scrollPane = new ScrollPane();
Pane content = new Pane();
final CategoryAxis xAxis = new CategoryAxis();
final NumberAxis yAxis = new NumberAxis(12, 20, 1);
yAxis.setSide(Side.RIGHT);
qChart=new LineChart<String,Number>(xAxis, yAxis);
qChart.setPrefSize(3000, 250);
content.getChildren().add(qChart);
scrollPane.setContent(content);
Circle immovableObject = new Circle(30, Color.RED);
content.getChildren().add(immovableObject);
primaryStage.setScene(new Scene(scrollPane, 300, 300));
primaryStage.show();
yAxis.layoutXProperty().bind(
scrollPane.hvalueProperty()
.multiply(
content.widthProperty()
.subtract(
new ScrollPaneViewPortWidthBinding(scrollPane))));
}
// we need this class because Bounds object doesn't support binding
private static class ScrollPaneViewPortWidthBinding extends DoubleBinding {
private final ScrollPane root;
public ScrollPaneViewPortWidthBinding(ScrollPane root) {
this.root = root;
super.bind(root.viewportBoundsProperty());
}
@Override
protected double computeValue() {
return root.getViewportBounds().getWidth();
}
}
public static void main(String[] args) { launch(); }
}
任何解决上述问题的想法或更好的方法来实现这一目标?
由于
答案 0 :(得分:1)
这是一个小修改,使用setTranslateX方法而不是layoutXProperty,使用滚动条移动yAxis和圆圈。
import javafx.application.Application;
import javafx.beans.binding.DoubleBinding;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class FancyScrollPane extends Application {
@Override
public void start(Stage primaryStage) {
ScrollPane scrollPane = new ScrollPane();
Pane content = new Pane();
scrollPane.setContent(content);
// adding background
content.getChildren().add(new Rectangle(500, 500, Color.GREEN));
Circle immovableObject = new Circle(30, Color.RED);
content.getChildren().add(immovableObject);
primaryStage.setScene(new Scene(scrollPane, 300, 300));
primaryStage.show();
immovableObject.layoutXProperty().bind(
scrollPane.hvalueProperty()
.multiply(
content.widthProperty()
.subtract(
new ScrollPaneViewPortWidthBinding(scrollPane))));
}
// we need this class because Bounds object doesn't support binding
private static class ScrollPaneViewPortHeightBinding extends DoubleBinding {
private final ScrollPane root;
public ScrollPaneViewPortHeightBinding(ScrollPane root) {
this.root = root;
super.bind(root.viewportBoundsProperty());
}
@Override
protected double computeValue() {
return root.getViewportBounds().getHeight();
}
}
// we need this class because Bounds object doesn't support binding
private static class ScrollPaneViewPortWidthBinding extends DoubleBinding {
private final ScrollPane root;
public ScrollPaneViewPortWidthBinding(ScrollPane root) {
this.root = root;
super.bind(root.viewportBoundsProperty());
}
@Override
protected double computeValue() {
return root.getViewportBounds().getWidth();
}
}
public static void main(String[] args) { launch(); }
}