ScrollPane JavaFX中图形上的静态标签

时间:2018-09-25 11:24:55

标签: java javafx

我正在尝试绘制多个彼此相邻的图形,其中图形的轴可以位于视口之外。我在嵌套在ScrollPane中的HBox中绘制每个图形。这仅适用于绘制图形的Y轴,但是我想将X轴的标签固定在屏幕上,这样当垂直滚动时,这些标签将始终可见。

我尝试创建一个StackPane,其中嵌套了上面提到的ScrollPane和HBox,第二个HBox嵌套了一个静态层。不幸的是,这破坏了ScrollPane的滚动功能。

有没有办法将标签固定在Y轴上,同时仍可以在X方向上滚动?

当前的FXML:

<VBox>
    <ScrollPane>
        <HBox>

        </HBox>
    </ScrollPane>
</VBox>

我尝试过的事情:

<VBox>
    <StackPane>
        <ScrollPane>
            <HBox>

            </HBox>
        </ScrollPane>
        <HBox>

        </HBox>
    <StackPane>
</VBox>

1 个答案:

答案 0 :(得分:0)

我能想到的一种方法是处理ScrollBar而不是ScrollPane。您可以使用轴的上下边界设置scrollBar的最小值/最大值。并在滚动值更改时相应地更新轴范围。像..

final AreaChart chart = new AreaChart(xAxis, yAxis);
        ScrollBar scroll = new ScrollBar();
        scroll.setMin(chartLowerBound);
        scroll.setMax(chartUpperBound);
        scroll.setVisibleAmount(10 * tickUnit);
        scroll.valueProperty().addListener((obs, old, nxtLb) -> {
            double nxtUb = nxtLb.doubleValue() + (10 * tickUnit);
            xAxis.setUpperBound(nxtUb);
            xAxis.setLowerBound(nxtLb.doubleValue());
        });

下面是一个快速工作的示例。尝试了解基本逻辑并根据需要实施。

import java.util.Random;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.chart.AreaChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.control.ScrollBar;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ScrollableChartDemo extends Application {

    public static void main(String... args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setTitle("Scrollable Chart");
        Random random = new Random(12);

        double tickUnit = .04;
        double chartLowerBound = 0;
        double chartUpperBound = 4;

        final ObservableList<Data> seriesData = FXCollections.observableArrayList();
        Series series = new Series("Series 1", seriesData);

        final ObservableList<Data> series2Data = FXCollections.observableArrayList();
        Series series2 = new Series("Series 2", series2Data);

        double tempoXAxis = 0.0;
        for (int i = 0; i < 100; i++) {
            seriesData.add(new Data(tempoXAxis, random.nextInt(12)));
            series2Data.add(new Data(tempoXAxis, random.nextInt(12)));
            tempoXAxis += tickUnit;
        }

        final ObservableList<Series> allSeriesData = FXCollections.observableArrayList(series, series2);

        NumberAxis xAxis = new NumberAxis("Time", 0, (10 * tickUnit), tickUnit);
        NumberAxis yAxis = new NumberAxis();

        final AreaChart chart = new AreaChart(xAxis, yAxis);
        chart.getData().addAll(allSeriesData);
        VBox.setVgrow(chart, Priority.ALWAYS);
        ScrollBar scroll = new ScrollBar();
        scroll.setMin(chartLowerBound);
        scroll.setMax(chartUpperBound - (10 * tickUnit));
        scroll.setVisibleAmount(10 * tickUnit);
        scroll.valueProperty().addListener((obs, old, nxtLb) -> {
            double nxtUb = nxtLb.doubleValue() + (10 * tickUnit);
            xAxis.setUpperBound(nxtUb);
            xAxis.setLowerBound(nxtLb.doubleValue());
        });

        chart.setOnScroll((ev) -> {
            double nxtUb;
            double nxtLb;
            if (ev.getDeltaY() > 0) {
                nxtUb = xAxis.getUpperBound() + tickUnit;
                if (nxtUb > chartUpperBound) {
                    nxtUb = chartUpperBound;
                }
                nxtLb = nxtUb - (10 * tickUnit);
            } else {
                nxtLb = xAxis.getLowerBound() - tickUnit;
                if (nxtLb < chartLowerBound) {
                    nxtLb = chartLowerBound;
                }
                nxtUb = nxtLb + (10 * tickUnit);
            }
            xAxis.setUpperBound(nxtUb);
            xAxis.setLowerBound(nxtLb);
            scroll.setValue(nxtLb);
            ev.consume();
        });


        VBox vb = new VBox();
        vb.setSpacing(5);
        vb.getChildren().addAll(chart, scroll);
        Scene scene = new Scene(vb);
        stage.setScene(scene);
        stage.setWidth(1000);
        stage.setHeight(700);
        stage.show();
    }
}