#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());
. И не используйте необработанные типы.