Попытка добавить данные в TableView из ArrayList (JavaFX)

#java #javafx #tableview #observablelist

#java #javafx #просмотр таблицы #observablelist

Вопрос:

Я пытаюсь заполнить TableView данными, которые находятся в ObservableList, но они не отображаются при запуске программы.

Вот части моей программы:

     private TableView<Crypto> tableView = new TableView<Crypto>();
    private static ArrayList<Crypto> cryptoData = new ArrayList();
    private static ObservableList<Crypto> data = FXCollections.observableArrayList(cryptoData);
    
    //*******Crypto Class************
    static class Crypto{
        private SimpleStringProperty coinName, 
        coinsBought,
        costPerCoin,
        totalSpent,
        currentPrice,
        currentValue,
        profit,
        roi;

        public String getcoinName() {
            return coinName.get();
        }
        public String getCoinsBought() {
            return coinsBought.get();
        }
        public String getCostPerCoin() {
            return costPerCoin.get();
        }
        public String getTotalSpent() {
            return totalSpent.get();
        }
        public String getCurrentPrice() {
            return currentPrice.get();
        }
        public String getCurrentValue() {
            return currentValue.get();
        }
        public String getProfit() {
            return profit.get();
        }
        public String getRoi() {
            return roi.get();
        }

        Crypto(String name, String numBought, String costPerCoin, String totalSpent, String curPrice, String curValue, String profit, String roi){
            this.coinName = new SimpleStringProperty(name);
            this.coinsBought = new SimpleStringProperty(numBought);
            this.costPerCoin = new SimpleStringProperty(costPerCoin);
            this.totalSpent = new SimpleStringProperty(totalSpent);
            this.currentPrice = new SimpleStringProperty(curPrice);
            this.currentValue = new SimpleStringProperty(curValue);
            this.profit = new SimpleStringProperty(profit);
            this.roi = new SimpleStringProperty(roi);
        }

        @Override
        public String toString() {
            return ("["   coinName.get()   ", "   coinsBought.get()   ", "   costPerCoin.get()   ", "  
                    totalSpent.get()   ", "   currentPrice.get()   ", "   currentValue.get()    ", "  
                    profit.get()   ", "   roi.get()   "]");

        }

    }//*********END Crypto Class*************
 
     @Override
    public void start(Stage primaryStage) {
        try {
            GridPane root = new GridPane();

            //title text
            Text titleText = new Text();
            titleText.setText("Crypto Portfolio");
            titleText.setY(600);
            titleText.setFont(Font.font("Veranda", FontWeight.BOLD, FontPosture.REGULAR,40));

            //refresh button
            Button refresh = new Button("Refresh Prices");
            refresh.setOnAction(e -> {
                //ADD button refresh
            });

            //total amount text
            Text totalDollar = new Text();
            totalDollar.setText(getTotalDollar());

            //table columns
            TableColumn coinColumn = new TableColumn("Coin");
            coinColumn.setCellValueFactory(new PropertyValueFactory<>("coinName"));

            TableColumn costColumn = new TableColumn("Cost");
            costColumn.setCellValueFactory(new PropertyValueFactory<>("totalSpent"));

            TableColumn coinBoughtColumn = new TableColumn("Coins Bought");
            coinBoughtColumn.setCellValueFactory(new PropertyValueFactory<>("coinsBought"));

            TableColumn costPerCoinColumn = new TableColumn("Cost per Coin");
            costPerCoinColumn.setCellValueFactory(new PropertyValueFactory<>("costPerCoin"));

            TableColumn currentPriceColumn = new TableColumn("Current Coin Price");
            currentPriceColumn.setCellValueFactory(new PropertyValueFactory<>("currentPrice"));

            TableColumn currentValueColumn = new TableColumn("Curren Value");
            currentValueColumn.setCellValueFactory(new PropertyValueFactory<>("currentValue"));

            TableColumn profitColumn = new TableColumn("Profit");
            profitColumn.setCellValueFactory(new PropertyValueFactory<>("profit"));

            TableColumn roiColumn = new TableColumn("ROI");
            roiColumn.setCellValueFactory(new PropertyValueFactory<>("roi"));


            tableView.setItems(data);
            tableView.getColumns().addAll(coinColumn, costColumn, coinBoughtColumn, costPerCoinColumn, currentPriceColumn, currentValueColumn, profitColumn, roiColumn);


            Scene scene = new Scene(root,1200,900);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            root.setHgap(10);
            root.setVgap(10);

            //sets gridLines visible for debug
            root.setGridLinesVisible(true);

            primaryStage.setScene(scene);
            primaryStage.setTitle("Mike's Crypto Portfolio");
            root.add(titleText, 0,0);
            root.add(refresh, 3, 0);
            root.add(tableView, 0, 1);

            

            primaryStage.show();

            new Thread () {
                @Override
                public void run() {
                    try {
                        readCSV("crypto.csv");
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                };
            }.start();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }//*****************END Start***************************
}
 

Я думал, что если я добавлю это, это сработает, но я получаю ПРЕДУПРЕЖДЕНИЕ: не удается получить свойство ‘coinName’ в PropertyValueFactory: javafx.scene.control.cell.PropertyValueFactory@2cc2c23 с предоставленным типом класса: приложение класса.Main$Crypto java.lang.Исключение IllegalStateException: не удается прочитать из нечитаемого свойства coinName

но для всего, кроме coinName, ошибка также добавляет: java.lang.RuntimeException: java.lang.Исключение IllegalAccessException: класс com.sun.javafx.reflect.Trampoline не может получить доступ к члену класса application.Main $ Crypto с модификаторами «public»

 for(Crypto coin : cryptoData) {
            data.add(coin);
        }
 

Комментарии:

1. класс должен быть общедоступным

2. @kleopatra боже мой… вот и все! ха-ха, спасибо!! Я ненавижу, когда это так просто.

3. Однако лучше предоставить средства доступа к свойствам (а не только к их значениям) и напрямую реализовать фабрики значений ячеек. Т.е. Определить public StringProperty coinNameProperty() { return coinName ; } и затем coinColumn.setCellValueFactory( cd -> cd.getValue().coinNameProperty()); . И не используйте необработанные типы.