Scrollpane line chart with fixed view y axis JavaFX

我们两清 提交于 2019-12-06 09:05:04

问题


I'm trying to make a scrollable chart where the Y-axis stays in view regardless of the cursor position in the scrollbar (by default since the Y-axis informations is at the end of the view, you would only see it after you scroll enough to see the end)

Here is an example what Im trying to accomplish:

Notice that even though the scrollbar position is midway-through, the Y-axis text(price) still remains in view

I looked around the web and was only able to find a single example of something similar but it does not appear to work with a line chart inside the scrollPane.

Always visible when scrolled anchored Node in Java FX 2.0?

The above works with a Circle object but changing to a Line Chart will result in "Exception:A bound value cannot be set" as it seems to automatically call set layout when using Line chart inside a scrollpane

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(); }
}

Any ideas to get around the above issue or a better way to accomplish this ?

Thanks


回答1:


Here is a little modification that moves the yAxis and the circle with the scroll bar using the setTranslateX method rather than the layoutXProperty.

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(); }
}


来源:https://stackoverflow.com/questions/38030926/scrollpane-line-chart-with-fixed-view-y-axis-javafx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!