Как создать BarChart или LineChart в Javafx, используя ObservableLists - PullRequest
0 голосов
/ 14 апреля 2019

Я пытаюсь сгенерировать статистические графики (BarCharts и LineCharts) из данных, сохраненных в базе данных sql с использованием Java. Ожидается, что данные будут время от времени меняться.

Я пытался использовать ObservableLists, но получаю сообщения об ошибках.

Ниже приведено то, что я пробовал до сих пор; ПРИМЕЧАНИЕ: это находится в классе DatabaseHandler

public ObservableList<BarChart.Data> getItemGraphStatistics(){
        ObservableList<BarChart.Data> data = FXCollections.observableArrayList();

        String sql = "SELECT itemID, COUNT(*) FROM (SELECT itemID FROM SALES UNION ALL SELECT itemID FROM STOCK) t GROUP BY itemID";
        System.out.println(sql );
        ResultSet rs = handler.execQuery(sql);
        try{

            while(rs.next()){
                String item= rs.getString("itemID");
                int count = rs.getInt(2);

                data.add(new BarChart.Data(item+ "(" + count + ")", count));

            }
        } catch (SQLException ex) {
            Logger.getLogger(DatabaseHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
        return data;

    }

При запуске выше получаю

java.lang.ClassCastException: javafx.scene.chart.XYChart$Data cannot be cast to javafx.scene.chart.XYChart$Series

Когда я пытаюсь изменить BarChart.Data на BarChart.Series, я не могу преобразовать int в сообщение об ошибке observableList.

Ниже приведен пример испытания вышеуказанного;

import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXRadioButton;
import com.jfoenix.controls.JFXTextField;
import java.net.URL;
import java.util.Calendar;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.ResourceBundle;
import java.util.concurrent.TimeUnit;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.PieChart;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.DatePicker;
import javafx.scene.control.ToggleGroup;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import sales.manager.database.DatabaseHandler;

/**
 * FXML Controller class
 *
 * @author Garande
 */
public class PerformanceAnalyzerController implements Initializable {

    @FXML
    private AnchorPane analysisHandler;
    @FXML
    private AnchorPane graphHandler;
    @FXML
    private PieChart piechart;
    @FXML
    private BarChart<?, ?> barchart;
    @FXML
    private LineChart<?, ?> linechart;

    @FXML
    private NumberAxis yBarGraph;
    @FXML
    private CategoryAxis xBarGraph;
    @FXML
    private NumberAxis yLineGraph;
    @FXML
    private CategoryAxis xLineGraph;

    DatabaseHandler handler = DatabaseHandler.getInstance();

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {


    }    

    @FXML
    private void performAnalysisOperation(ActionEvent event) {
        //Performing analysis operation

        barchart.setData(handler.getItemGraphStatistics());
        graphHandler.getChildren().add(barchart);
    }
}

1 Ответ

1 голос
/ 14 апреля 2019

Свойство data для XYChart содержит ObservableList<XYChart.Series>.Каждый XYChart.Series также имеет свойство data, но содержит ObservableList<XYChart.Data>.Проблема в том, что ваш метод возвращает ObservableList<XYChart.Data>, который вы затем пытаетесь установить на XYChart.data - типы не совпадают.Я не уверен, как вы получаете ClassCastException, поскольку ваш код даже не должен компилироваться.

Вам нужно свернуть список данных в серии, а затем добавить серию в диаграмму.Вам также следует избегать использования необработанных типов Series, и Data имеют параметры типа, но вы их не указываете.Исходя из того, как вы строите Data, ваш код должен выглядеть примерно так (какой-то код для краткости опущен):

public class PerformanceAnalyzerController {

    @FXML private BarChart<String, Number> barChart;

    @FXML
    private void performAnalysisOperation(ActionEvent event) {
        //Performing analysis operation

        ObservableList<XYChart.Data<String, Number>> data = handler.getItemsGraphicsStatisitics();
        XYChart.Series<String, Number> series = new XYChart.Series<>("Series Name", data);

        barchart.getData().setAll(series);
        graphHandler.getChildren().add(barchart);
    }

}

И:

// Use generic types
public ObservableList<XYChart.Data<String, Number>> getItemGraphStatistics(){
    ObservableList<XYChart.Data<String, Number>> data = FXCollections.observableArrayList();

    String sql = "SELECT itemID, COUNT(*) FROM (SELECT itemID FROM SALES UNION ALL SELECT itemID FROM STOCK) t GROUP BY itemID";
    System.out.println(sql );
    ResultSet rs = handler.execQuery(sql);
    try{

        while(rs.next()){
            String item= rs.getString("itemID");
            int count = rs.getInt(2);

            // add diamond operator "<>"
            data.add(new XYChart.Data<>(item+ "(" + count + ")", count));

        }
    } catch (SQLException ex) {
        Logger.getLogger(DatabaseHandler.class.getName()).log(Level.SEVERE, null, ex);
    }
    return data;

}

Примечание: я заменил использование BarChart.Data на XYChart.Data, но я не думаю, что это имеет значение в этом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...