2016-01-22 3 views
1

У меня возникли проблемы с обновлением таблицы в моем классе java.Обновление Javafx tableview при смене объекта

package gameStats.controllers; 

import gameStats.Main; 
import gameStats.model.Team; 
import javafx.animation.KeyFrame; 
import javafx.animation.Timeline; 
import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.collections.FXCollections; 
import javafx.collections.ListChangeListener; 
import javafx.collections.ObservableList; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.fxml.FXML; 
import javafx.fxml.FXMLLoader; 
import javafx.fxml.Initializable; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.scene.control.*; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.paint.Color; 
import javafx.stage.Stage; 
import javafx.util.Duration; 

import java.io.IOException; 
import java.net.URL; 
import java.util.ArrayList; 
import java.util.ResourceBundle; 

public class MainController implements Initializable { 

    private Timeline timeline = new Timeline(); 
    @FXML 
    private Label timerText; 
    @FXML 
    private Button startTimerButton, stopTimerButton, resetTimerButton, addTeamButton, addPointButton, removePointButton, newTimeButton; 
    @FXML 
    private TextField teamNameTextfield; 
    @FXML 
    private TableView teamView; 
    @FXML 
    private TableColumn<Team, SimpleStringProperty> nameCol; 
    @FXML 
    private TableColumn<Team, SimpleIntegerProperty> pointCol; 

    private ObservableList<Team> obsTeamList; 

    private int min; 
    private int startTimeSec, startTimeMin; 
    private Parent borderPane; 
    public BorderPane timeBorderPane; 
    private boolean isRunning; 

    public void startTimer() { 
     if(isRunning == false) { 
      if (!(startTimeMin < 0)) { 
       KeyFrame keyframe = new KeyFrame(Duration.seconds(1), new EventHandler<ActionEvent>() { 
        @Override 
        public void handle(ActionEvent event) { 

         startTimeSec--; 
         boolean isSecondsZero = startTimeSec == 0; 
         boolean timeToChangeBackground = startTimeSec == 0 && startTimeMin == 0; 

         if (isSecondsZero) { 
          startTimeMin--; 
          startTimeSec = 60; 
         } 
         if (timeToChangeBackground) { 
          timeline.stop(); 
          startTimeMin = 0; 
          startTimeSec = 0; 
          timerText.setTextFill(Color.RED); 

         } 

         timerText.setText(String.format("%d min, %02d sec", startTimeMin, startTimeSec)); 

        } 
       }); 
       timerText.setTextFill(Color.BLACK); 
       startTimeSec = 60; // Change to 60! 
       startTimeMin = min - 1; 
       timeline.setCycleCount(Timeline.INDEFINITE); 
       timeline.getKeyFrames().add(keyframe); 
       timeline.playFromStart(); 
       isRunning = true; 
      } else { 
       Alert alert = new Alert(Alert.AlertType.INFORMATION, "You have not entered a time!"); 
       alert.showAndWait(); 
      } 
     }else { 
      timeline.play(); 
     } 

    } 

    public void setTimer() { 
     try { 
      FXMLLoader loader = new FXMLLoader(); 
      loader.setLocation(Main.class.getResource("newTimeDialog.fxml")); 
      Parent newTimeBorderPane = (BorderPane) loader.load(); 
      borderPane = newTimeBorderPane; 
      Scene scene = new Scene(newTimeBorderPane); 
      Stage primaryStage = new Stage(); 
      primaryStage.setScene(scene); 
      primaryStage.showAndWait(); 
      if (!primaryStage.isShowing()) { 
       min = NewTimeController.getMin(); 
       timerText.setText(min + "min, " + 00 + "sec"); 
      } else { 

      } 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 


    } 

    public void stopTimer() { 

     timeline.pause(); 
    } 

    public void resetTimer() { 
     timeline.stop(); 
     startTimeSec = 60; 
     startTimeMin = min-1; 
     timerText.setText(String.format("%d min, %02d sec", startTimeMin, startTimeSec)); 
    } 

    public void createTeam(){ 

     SimpleStringProperty name = new SimpleStringProperty(teamNameTextfield.getText()); 
     SimpleIntegerProperty startPoint = new SimpleIntegerProperty(0); 
     if(!(obsTeamList.size() == 0)){ 
      for (Team t : obsTeamList) { 
       if (!t.getName().equals(name)) { 
        obsTeamList.add(new Team(name, startPoint)); 
        teamView.getItems().setAll(obsTeamList); 
       }else { 
        Alert alert = new Alert(Alert.AlertType.INFORMATION, "Holdet eksistere allerede!"); 
        alert.showAndWait(); 
       } 
      } 
     }else{ 
      obsTeamList.add(new Team(name, startPoint)); 
      teamView.getItems().setAll(obsTeamList); 
     } 

    } 

    public void addPoint(){ 
     Team teamToAddPointsTo = (Team) teamView.getSelectionModel().getSelectedItem(); 
     teamToAddPointsTo.setPoints(new SimpleIntegerProperty(1)); 
    } 
    @Override 
    public void initialize(URL location, ResourceBundle resources) { 
     obsTeamList = FXCollections.observableArrayList(new ArrayList<>()); 
     nameCol.setCellValueFactory(new PropertyValueFactory<>("name")); 
     pointCol.setCellValueFactory(new PropertyValueFactory<>("points")); 


    } 
} 

Класс модели:

package gameStats.model; 

import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 

/** 
* Created by lassebjorklund on 21/01/16. 
* For JuniorEvent_kampdata 
*/ 
public class Team { 

    private SimpleStringProperty name; 
    private SimpleIntegerProperty points; 

    public Team(SimpleStringProperty name, SimpleIntegerProperty points) { 
     this.name = name; 
     this.points = points; 
    } 

    public String getName() { 
     return name.get(); 
    } 

    public SimpleStringProperty nameProperty() { 
     return this.name; 
    } 

    public int getPoints() { 
     return points.get(); 
    } 

    public SimpleIntegerProperty pointsProperty() { 
     return this.points; 
    } 

    public void setName(String name) { 
     this.name.set(name); 
    } 

    public void setPoints(SimpleIntegerProperty points) { 
     this.points.add(points); 
    } 

    @Override 
    public String toString() { 
     return getName() + " : " + getPoints(); 
    } 
} 

Я хочу, чтобы иметь возможность обновить точки для выбранной команды в виде таблицы. Я хочу, чтобы это произошло, когда я нажимаю кнопку, которая вызывает метод «addPoint». Но я не знаю, как это сделать.

+0

Привет @Lasse Я предлагаю вам изменить свой заголовок на что-то более описательное, – Llewellyn1411

+1

Выполнено, и спасибо @ Llewellyn1411 – Lasse

+1

Без вас, рассказывая нам, как вы хотите обновить представление (каким должен быть результат и когда это должно произойти), это будет довольно трудно понять. – hotzst

ответ

3

У вас есть несколько проблем с кодом.

  1. Тип столбца должен быть основным типом данных, а не типом свойства. Для SimpleStringProperty использовать TableColumn<Team, String>. Для SimpleIntegerProperty использовать TableColumn<Team, Integer> или TableColumn<Team, Number>.
  2. Метод setPoints должен принимать int или Integer, а не SimpleIntegerProperty. Он должен быть того же типа, что и getPoints.
  3. Внутри setPoints, вы должны использовать points.set. points.add создает новый NumberExpression, который представляет собой добавление двух свойств, но не изменяет фактическое свойство.

На этой же заметке, вероятно, неплохо иметь фактические свойства Team в качестве конечных полей и изменять их значения. См. this tutorial для получения дополнительной информации.

+0

Спасибо, что решил мою проблему. – Lasse

+1

[JavaFX 8 версия учебника связана] (http://docs.oracle.com/javase/8/javafx/properties-binding-tutorial/binding.htm#JFXBD107) (хотя я думаю, что это может быть точно такая же статья), и (более полезно) [полезная презентация PowerPoint] (http://www.oracle.com/us/technologies/java/javafx-2-prog-model-1524061.pdf). –