Интервал между линейными диаграммами JavaFX в GridPane

Итак, сейчас я пытаюсь написать программу для отображения данных в линейных диаграммах JavaFX. Моя основная панель представляет собой BorderPane с некоторыми функциями сверху/слева/справа/и т. д. В центре панели я хочу отображать линейные диаграммы. Минимум 1 и максимум 4.

Поэтому я подумал о том, чтобы установить панель сетки в центре главной панели, чтобы добиться результата, подобного этому:

Образец панели сетки

Теперь моя проблема заключается в том, что когда я пытаюсь добавить LineCharts в GridPane (с .add(chart, 0, 0), диаграмма просто не совпадает с родительской. То же самое, если я продолжаю добавлять больше диаграмм. Оказывается, что-то вроде этого:

Что-то вроде этого

Я просмотрел много материала о сопоставлении родителей, но почему-то я ничего не получаю: / Мне нужно знать размер «центра» пограничной панели, тогда я мог бы соответствующим образом изменить размер LineCharts. Но не могу найти... может кто знает?

Ваше здоровье!


person hans_maulwurf    schedule 13.02.2017    source источник
comment
Не могли бы вы получить ширину указанной панели, разделить ее на два и сделать то же самое с высотой? Быстрый поиск в Google нашел это   -  person Taelsin    schedule 14.02.2017
comment
Да, я пробовал это, но результат то ли удовлетворительный, то ли очень элегантный. Когда у меня есть 4 диаграммы в сетке, я попытался установить prefWidth/Height для всех на половину размеров GridPane. Каким-то образом диаграммы все еще имеют разные размеры, начиная с диаграммы 1, которая является самой большой, и диаграммы 4, являющейся самой маленькой:/   -  person hans_maulwurf    schedule 16.02.2017


Ответы (1)


Вы можете добавить прослушиватель в GridPane для размера его дочерних элементов и обновить ограничения макета дочерних узлов на основе размера списка дочерних элементов.

диаграммы

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.collections.ObservableList;
import javafx.geometry.*;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;

import java.util.stream.IntStream;

public class GridViewer extends Application {
    @Override
    public void start(final Stage stage) throws Exception {
        ChartGrid grid = new ChartGrid();

        grid.getChildren().setAll(
                IntStream.range(1, 5)
                        .mapToObj(this::createLineChart)
                        .toArray(Chart[]::new)
        );

        stage.setScene(new Scene(grid));
        stage.show();
    }

    class ChartGrid extends GridPane {
        ChartGrid() {
            setHgap(5);
            setVgap(5);
            setPadding(new Insets(5));

            setPrefSize(500, 500);

            Bindings.size(getChildren()).addListener((observable, oldSize, newSize) -> {
                ObservableList<Node> nodes = getChildren();
                for (int i = 0; i < newSize.intValue(); i++) {
                    GridPane.setConstraints(
                            nodes.get(i),
                            i / 2, i % 2,
                            1, 1,
                            HPos.CENTER, VPos.CENTER,
                            Priority.ALWAYS, Priority.ALWAYS
                    );
                }
            });
        }
    }

    private Chart createLineChart(int idx) {
        NumberAxis xAxis = new NumberAxis();
        NumberAxis yAxis = new NumberAxis();
        LineChart<Number, Number> chart = new LineChart<>(xAxis, yAxis);
        chart.setTitle("Chart " + idx);
        chart.setMinSize(0, 0);

        return chart;
    }

    public static void main(String[] args) throws Exception {
        launch(args);
    }
}

Примечание. важной частью этого решения является установка минимального размера диаграмм на 0:

chart.setMinSize(0, 0);

Это связано с тем, что если размер доступной области GridPane меньше, чем сумма минимального размера диаграмм (которая по умолчанию не равна 0), то диаграммы начнут рисоваться с наложением друг на друга, а это не то, что вам нужно. .

person jewelsea    schedule 13.02.2017
comment
Большое спасибо за ваши усилия, это было именно то, что мне нужно! Спасибо! - person hans_maulwurf; 16.02.2017
comment
Еще один вопрос о заполнении сетки: я хочу динамически добавлять/удалять графики (==> не через поток .setAll). Когда я использую grid.add(chart, 0, 0), например, я должен указать строку/столбец, поэтому результатом будет GridPane, разделенный на четыре квадрата, с одной диаграммой в верхнем левом углу. Это не является неправильным само по себе, потому что все идеально подходит, когда у меня всего 4 диаграммы. Но с одной диаграммой диаграмма должна фактически отображаться по всей GridPane. Какой способ / методы вы рекомендуете, чтобы сделать это правильно? (Я также пробовал .getChildren.add, а затем .getChildren.set, но результат тот же, что и выше) - person hans_maulwurf; 17.02.2017