Построение Line Chart в JavaFX из текстового файла

202
25 ноября 2021, 03:30

Программа состоит из двух окон. В первом окне вводится путь текстового файла, из которого считываются данные (а именно, координаты Х и У точек) для построения графика. По нажатию кнопки формируется внешний вид второго окна, вызывается метод формирования двух массивов, содержащих координаты Х и У.
Проблема в том, что пропускается некоторое количество точек и получается кривая, не соответствующая заданным координатам (см. скриншот).

//координаты точек в .txt файле
20  100
50  150
100 200
150 100
200 150
300 500
400 200
500 800
1000    500

Ниже представлен код программы.

//в Main классе формируется внешний вид первого окна из .fxml файла
public class Main extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception{
        FXMLLoader mainWindowLoader = new FXMLLoader();
        mainWindowLoader.setLocation(getClass().getResource("/sample/mainWindow.fxml"));
        mainWindowLoader.load();
        Parent root = mainWindowLoader.getRoot();
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
    public static void main(String[] args) {
        launch(args);
    }
}
//контроллер первого окна
public class MainWindowController {
    ChartWindowController chartWindowController;
    @FXML
    private ResourceBundle resources;
    @FXML
    private URL location;
    @FXML
    private TextField filePathTextField;
    @FXML
    private Button buildButton;
    @FXML
    void initialize() {
//по нажатию кнопки формируется внешний вид второго окна
        buildButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                FXMLLoader chartWindowLoader = new FXMLLoader();
                chartWindowLoader.setLocation(getClass().getResource("/sample/chartWindow.fxml"));
                try {
                    chartWindowLoader.load();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Parent root = chartWindowLoader.getRoot();
                Stage chartStage = new Stage();
                chartStage.setScene(new Scene(root));
//получение экземпляра контроллера второго окна
                chartWindowController = (ChartWindowController) chartWindowLoader.getController();
//формирование массивов данных из текстового файла
                createChartData(filePathTextField.getText());
                chartStage.show();
            }
        });
    }
//чтение из текстового файла строк, разделенных знаком табуляции и 
//формирование массивов координат Х и У
    void createChartData(String path) {
        ArrayList<Double> xCoords = new ArrayList<>();
        ArrayList<Double> yCoords = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
            do {
                String s = reader.readLine();
                if (s == null) break;
                String[] s1 = s.split("\t");
                xCoords.add(Double.parseDouble(s1[0]));
                yCoords.add(Double.parseDouble(s1[1]));
            } while (reader.readLine() != null);
        } catch (IOException e) {
            e.printStackTrace();
        }
//передача массивов координат в метод контроллера второго окна для построения
        chartWindowController.drawChart(xCoords,yCoords);
    }
}
//контроллер второго окна, содержащего график
public class ChartWindowController {
    @FXML
    private ResourceBundle resources;
    @FXML
    private URL location;
    @FXML
    private LineChart<Number, Number> chart;
    @FXML
    void initialize() {
    }
//формирование данных для графика из двух массивов
    void drawChart(ArrayList<Double> x, ArrayList<Double> y) {
        chart.getData().clear();
        XYChart.Series series = new XYChart.Series();
        for (int i = 0; i < x.size(); i++) {
            series.getData().add(new XYChart.Data(x.get(i), y.get(i)));
        }
        chart.getData().add(series);
    }
}

Answer 1

Вызывая reader.readLine() дважды в цикле (в теле цикла и в условии while) вы перескакиваете через строку, т.к. readLine смещает указатель при каждом вызове. Стандартное использование:

String s = reader.readLine();
while ( s != null ) {
    String[] s1 = s.split("\t");
    xCoords.add(Double.parseDouble(s1[0]));
    yCoords.add(Double.parseDouble(s1[1]));
    s = reader.readLine();
}
READ ALSO
Время работы алгоритма

Время работы алгоритма

возникла небольшая проблемаНаписал программу, которая ищет 2 ближайшие точки 2-мя методами: декомпозиции и полным перебором

253
Spring cloud, auth-service

Spring cloud, auth-service

Создаю приложение на микросервисной архитектуре с использованием Spring Boot, Spring CloudКак пример я смотрю вот этот репозиторий

196
Java Timer Animation

Java Timer Animation

Необходимо по таймеру увеличивать и уменьшать сферу например за 5 секунд увеличить и за 5 секунд уменьшить, этот код работает, ну я не знаю...

181