滚动窗格JavaFX中图形上的静态标签

滚动窗格JavaFX中图形上的静态标签,java,javafx,Java,Javafx,我正在尝试绘制多个相邻的图形,其中图形的轴可以位于视口之外。我在HBox中绘制每个图形,HBox嵌套在滚动窗格中。这对于仅仅绘制图形的Y轴来说是很好的,但是我想保持X轴的标签固定在屏幕上,这样当一些垂直滚动时,标签将始终可见 我试着创建一个StackPane,其中嵌套了上面提到的ScrollPane和HBox,并创建了第二个HBox来创建一种静态层。不幸的是,这破坏了滚动窗格的滚动功能 有没有办法使标签固定在Y轴上,同时仍然可以在X方向上滚动 FXML当前: <VBox> &

我正在尝试绘制多个相邻的图形,其中图形的轴可以位于视口之外。我在HBox中绘制每个图形,HBox嵌套在滚动窗格中。这对于仅仅绘制图形的Y轴来说是很好的,但是我想保持X轴的标签固定在屏幕上,这样当一些垂直滚动时,标签将始终可见

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

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

FXML当前:

<VBox>
    <ScrollPane>
        <HBox>

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

我尝试的是:

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

            </HBox>
        </ScrollPane>
        <HBox>

        </HBox>
    <StackPane>
</VBox>

我能想到的一种方法是处理滚动条而不是滚动窗格。可以使用轴下限/上限设置滚动条的最小值/最大值。当滚动值发生变化时,相应地更新轴边界。类似于

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();
    }
}
import java.util.Random;
导入javafx.application.application;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.scene.scene;
导入javafx.scene.chart.AreaChart;
导入javafx.scene.chart.NumberAxis;
导入javafx.scene.chart.XYChart.Data;
导入javafx.scene.chart.XYChart.Series;
导入javafx.scene.control.ScrollBar;
导入javafx.scene.layout.Priority;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
公共类ScrollableChartDemo扩展了应用程序{
公共静态void main(字符串…参数){
发射(args);
}
@凌驾
public void start(Stage)引发异常{
stage.setTitle(“可滚动图表”);
随机数=新随机数(12);
双单位=0.04;
双chartLowerBound=0;
双上限=4;
最终ObservableList seriesData=FXCollections.observableArrayList();
系列=新系列(“系列1”,系列数据);
最终ObservableList series2Data=FXCollections.observableArrayList();
系列2=新系列(“系列2”,系列2数据);
双tempoXAxis=0.0;
对于(int i=0;i<100;i++){
seriesData.add(新数据(tempoXAxis,random.nextInt(12));
series2Data.add(新数据(tempoXAxis、random.nextInt(12));
tempoXAxis+=单位;
}
最终ObservableList allSeriesData=FXCollections.observableArrayList(系列,系列2);
NumberAxis xAxis=新的NumberAxis(“时间”,0,(10*滴答单位),滴答单位);
NumberAxis yAxis=新的NumberAxis();
最终面积图=新面积图(xAxis,yAxis);
chart.getData().addAll(allSeriesData);
VBox.setVgrow(图表、优先级、始终);
ScrollBar scroll=新的ScrollBar();
scroll.setMin(chartLowerBound);
scroll.setMax(chartUpperBound-(10*tickUnit));
滚动。设置可视挂载(10*单位);
scroll.valueProperty().addListener((obs,旧,nxtLb)->{
double nxtUb=nxtLb.doubleValue()+(10*单位);
xAxis.setUpperBound(nxtUb);
setLowerBound(nxtLb.doubleValue());
});
图表.设置克罗尔((ev)->{
双筒;
双nxtLb;
如果(ev.getDeltaY()>0){
nxtUb=xAxis.getUpperBound()+单位;
如果(nxtUb>图表上限){
nxtUb=图表上限;
}
nxtLb=nxtUb-(10*单位);
}否则{
nxtLb=xAxis.getLowerBound()-tickUnit;
如果(nxtLb
请提供一个示例来说明问题。