TableView не заполняется при получении ввода от пользователя, но заполняется при явном добавлении нового объекта - PullRequest
0 голосов
/ 13 июня 2018

Это первый раз, когда я использую 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;
}

note:Я использовал свой собственный класс дат, который я создал.

Я проверил, действительно ли метод работает, и 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 голосов
/ 14 июня 2018

Я не уверен, что я сделал, но я, кажется, исправил это.Вот моя реализация метода 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 () - единственные используемые методы.Остальные для проверки ошибок.

0 голосов
/ 13 июня 2018

Для начала стоит обратить внимание на свою модель (класс 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);
    }
}

Вы также должны изменить свою «базу данных».Вы должны использовать коллекцию 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);
    }
}
...