从用户获取输入时不会填充TableView,但在显式添加新Object时会填充

时间:2018-06-13 04:45:51

标签: java javafx arraylist tableview observablelist

这是我第一次使用JavaFX和TableView。我有一个应用程序,用户输入高尔夫分数,为他们生成差点值。

我有一个ArrayList,我用作我的"数据库":

public ArrayList<Score> scoreDB = new ArrayList<>();

将此作为添加值的方法:

public static Score scoreSubmit(DatePicker roundDate, TextField courseName, TextField courseRating, TextField courseSlope, TextField score)
{
    Score temp = new Score();
    //Wanted to use own Date class, must use this roundabout way to set the date correctly
    LocalDate tempDate = roundDate.getValue();

    temp.setRoundDate(tempDate.getMonthValue(), tempDate.getDayOfMonth(), tempDate.getYear());
    temp.setCourseName(courseName.getText());
    temp.setCourseRating(Double.valueOf(courseRating.getText()));
    temp.setCourseSlope(Double.valueOf(courseSlope.getText()));
    temp.setScore(Double.valueOf(score.getText()));

    return temp;
}

注意:我使用了自己创建的日期类。

我已经检查过该方法是否确实有效并且ArrayList确实收到了值。

这是我对TableView的构造:

//Table columns
    //Creating columns and setting the display to call the values from Score class
    TableColumn<Score, String> courseNameColumn = new TableColumn<>("Course Name");
    courseNameColumn.setMinWidth(100);
    courseNameColumn.setCellValueFactory(new PropertyValueFactory<>("courseName"));

    TableColumn<Score, Date> dateColumn = new TableColumn<>("Date");
    dateColumn.setMinWidth(100);
    dateColumn.setCellValueFactory(new PropertyValueFactory<>("roundDate"));

    TableColumn<Score, Double> scoreColumn = new TableColumn<>("Score");
    scoreColumn.setMinWidth(100);
    scoreColumn.setCellValueFactory(new PropertyValueFactory<>("score"));

    //This adds rating and slope under one column
    TableColumn courseDataColumn = new TableColumn("Course Data");
    TableColumn<Score, Double> courseRatingColumn = new TableColumn<>("Course Rating");
    TableColumn<Score, Double> courseSlopeColumn = new TableColumn<>("Course Slope");
    courseDataColumn.getColumns().addAll(courseRatingColumn, courseSlopeColumn);
    courseDataColumn.setMinWidth(100);
    courseRatingColumn.setCellValueFactory(new PropertyValueFactory<>("courseRating"));
    courseSlopeColumn.setCellValueFactory(new PropertyValueFactory<>("courseSlope"));

    scoreTable.getColumns().addAll(courseNameColumn, dateColumn, scoreColumn, courseDataColumn);

    displayLayout.setCenter(displaySP);
    displaySP.setBackground(new Background(new BackgroundFill(Paint.valueOf("#006400"), CornerRadii.EMPTY, Insets.EMPTY)));
    displaySP.getChildren().add(scoreTable);
    displayLayout.setBottom(displayHbox);

    scoreTable.setItems(addScore());

以下是我的分数类中的变量:

private double score = 0.0;
private double courseRating = 0.0;
private double courseSlope = 0.0;
private String courseName = "";
private Date roundDate;

以下是我的得分类吸气剂(我已经读过这些必须以某种方式命名才能起作用):

public double getScore()
{
    return score;
}
public String getCourseName()
{
    return courseName;
}
public Double getCourseSlope()
{
    return courseSlope;
}
public double getCourseRating()
{
    return courseRating;
}
public Date getRoundDate()
{
    return roundDate;
}

以下是返回可观察列表的方法:

public ObservableList<Score> addScore()
{
    ObservableList<Score> scores = FXCollections.observableArrayList();

   // scores.add(new Score());

    for (int i = 0; i < scoreDB.size(); i++)
    {
        scores.add(scoreDB.get(i));
    }

    return scores;
}

如果仅使用已注释的新Score(),则表格将使用此默认分数填充。使用for循环时,不会填充任何内容。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

对于初学者,你应该注意你的模型(Score类)。使用Properties很好(但不一定)。这样做的原因是您可以编辑值,更改将自动反映在视图中(TableView)。否则,如果对已添加的数据进行任何更改,则需要手动更新它,因为PropertyValueFactory将生成只读属性。

public class Score {
    private DoubleProperty score = new SimpleDoubleProperty(0.0);
    private DoubleProperty courseRating = new SimpleDoubleProperty(0.0);
    private DoubleProperty courseSlope = new SimpleDoubleProperty(0.0);
    private StringProperty courseName = new SimpleStringProperty("");
    private ObjectProperty<LocalDate> roundDate = new SimpleObjectProperty<>();

    public double getScore() {
        return score.get();
    }

    public DoubleProperty scoreProperty() {
        return score;
    }

    public void setScore(double score) {
        this.score.set(score);
    }

    public double getCourseRating() {
        return courseRating.get();
    }

    public DoubleProperty courseRatingProperty() {
        return courseRating;
    }

    public void setCourseRating(double courseRating) {
        this.courseRating.set(courseRating);
    }

    public double getCourseSlope() {
        return courseSlope.get();
    }

    public DoubleProperty courseSlopeProperty() {
        return courseSlope;
    }

    public void setCourseSlope(double courseSlope) {
        this.courseSlope.set(courseSlope);
    }

    public String getCourseName() {
        return courseName.get();
    }

    public StringProperty courseNameProperty() {
        return courseName;
    }

    public void setCourseName(String courseName) {
        this.courseName.set(courseName);
    }

    public LocalDate getRoundDate() {
        return roundDate.get();
    }

    public ObjectProperty<LocalDate> roundDateProperty() {
        return roundDate;
    }

    public void setRoundDate(LocalDate roundDate) {
        this.roundDate.set(roundDate);
    }
}

您还必须更改您的&#34;数据库&#34;。您必须使用Observable集合而不是普通List。这将允许您直接向其添加数据,它们将自动显示在表

public ObservableList<Score> scoreDB = FXCollections.observableArrayList();
...

//scoreTable.setItems(addScore());
scoreTable.setItems(scoreDB);

...

public void scoreSubmit() {
    Score temp = new Score();

    temp.setRoundDate(roundDate.getValue());
    temp.setCourseName(courseName.getText());
    temp.setCourseRating(Double.valueOf(courseRating.getText()));
    temp.setCourseSlope(Double.valueOf(courseSlope.getText()));
    temp.setScore(Double.valueOf(score.getText()));

    scoreDB.add(temp);
}

<强>更新

这是一个使用几乎所有结构的工作示例。数据输入不堪重负,因为NumberFormatException来电,您可能会收到Double#valueOf。为避免此问题,最好使用TextFormatter

public class Main extends Application {

    private DatePicker roundDate = new DatePicker();
    private TextField courseName = new TextField();
    private TextField courseRating = new TextField();
    private TextField courseSlope = new TextField();
    private TextField score = new TextField();
    private TableView<Score> scoreTable = new TableView<>();

    public ObservableList<Score> scoreDB = FXCollections.observableArrayList();

    @Override
    public void start(Stage primaryStage) throws Exception{

        //Table columns
        //Creating columns and setting the display to call the values from Score class
        TableColumn<Score, String> courseNameColumn = new TableColumn<>("Course Name");
        courseNameColumn.setMinWidth(100);
        courseNameColumn.setCellValueFactory(new PropertyValueFactory<>("courseName"));

        TableColumn<Score, LocalDate> dateColumn = new TableColumn<>("Date");
        dateColumn.setMinWidth(100);
        dateColumn.setCellValueFactory(new PropertyValueFactory<>("roundDate"));

        TableColumn<Score, Double> scoreColumn = new TableColumn<>("Score");
        scoreColumn.setMinWidth(100);
        scoreColumn.setCellValueFactory(new PropertyValueFactory<>("score"));

        //This adds rating and slope under one column
        TableColumn courseDataColumn = new TableColumn("Course Data");
        TableColumn<Score, Double> courseRatingColumn = new TableColumn<>("Course Rating");
        TableColumn<Score, Double> courseSlopeColumn = new TableColumn<>("Course Slope");
        courseDataColumn.getColumns().addAll(courseRatingColumn, courseSlopeColumn);
        courseDataColumn.setMinWidth(100);
        courseRatingColumn.setCellValueFactory(new PropertyValueFactory<>("courseRating"));
        courseSlopeColumn.setCellValueFactory(new PropertyValueFactory<>("courseSlope"));

        scoreTable.getColumns().addAll(courseNameColumn, dateColumn, scoreColumn, courseDataColumn);
        scoreTable.setItems(scoreDB);

        Button addButton = new Button("Add");
        addButton.setOnAction(e -> scoreSubmit());

        HBox displayHbox = new HBox();
        displayHbox.setSpacing(5);
        displayHbox.getChildren().addAll(roundDate, courseName, courseRating, courseSlope, score, addButton);

        BorderPane displayLayout = new BorderPane();
        displayLayout.setCenter(scoreTable);
        displayLayout.setBottom(displayHbox);

        primaryStage.setScene(new Scene(displayLayout));
        primaryStage.show();
    }

    public void scoreSubmit() {
        Score temp = new Score();

        temp.setRoundDate(roundDate.getValue());
        temp.setCourseName(courseName.getText());
        temp.setCourseRating(Double.valueOf(courseRating.getText()));
        temp.setCourseSlope(Double.valueOf(courseSlope.getText()));
        temp.setScore(Double.valueOf(score.getText()));

        scoreDB.add(temp);
    }

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

答案 1 :(得分:0)

我不确定我做了什么,但我好像修好了。这是我的scoreSubmit()方法实现:

 //Submit Button for score scene, implements method for setting Score Class variables
    Button scoreSubmit = GHINAppMethods.submitButton();
    scoreSubmit.defaultButtonProperty().bind(nameInput.focusedProperty());
    scoreSubmit.setOnAction(e ->
    {
        //checks to make sure values are correct
        switch (GHINAppMethods.checkScoreValues(courseRating, courseSlope, score))
        {
            //all values valid
            case 0:
            {
                //adds score to a "database" that will eventually be used in ScoreHistory class
                scoreDB.add(GHINAppMethods.scoreSubmit(roundDateTest, courseName, courseRating, courseSlope, score));
               //ScoreIterator has no use at this point
                System.out.println(scoreDB.get(scoreIterator));
                scoreIterator++;
                System.out.println(scoreIterator);
                System.out.println(scoreDB.size());
                GHINAppMethods.addAnotherScore(scoreTextFields, clearAll, displayScene, entryWindow, scoreTable, scores);
                break;
            }
            //rating invalid
            case 1:
            {
                courseRating.clear();
                GHINAppMethods.ratingInvalid();
                break;
            }
            //slope invalid
            case 2:
            {
                courseSlope.clear();
                GHINAppMethods.slopeInvalid();
                break;
            }
            //score invalid
            case 3:
            {
                score.clear();
                GHINAppMethods.scoreInvalid();
                break;
            }
            //Fatal System Error (shouldn't be used)
            default:
            {
                GHINAppMethods.fatalError();
                System.out.println("fatal error");
                System.exit(0);
                break;
            }
        }
    });

checkScoreValues()方法只是检查以确保值是正确的(我仍然错过了异常但它有帮助)。 checkScoreValues返回一个int,并且switch语句将执行。 scoreDB.add(...)和addAnotherScore()是唯一实际使用的方法。其他用于错误检查。