Gabriela
Gabriela

Reputation: 3

JavaFX: TableView fill column with specific data from ObservableList

I am working at a project for the university. I just learned Java and JavaFX.

I have a problem, maybe someone can help me.

With this little software you can plan tasks for the week. In the tableview you have columns from Monday to Friday.

I have a database, where I Can get objects „Auftragsverteilung“ (that means tasks, that are planned for a specific date). These objects have a serial number (= seriennr) and a date (= bearbeitungsdatum).

To fill the week in the tableview I get from the database all tasks planned for the week. The tasks for the week are saved in the ObservableList rechnerWochenansichtTabelle. You can select the week from the combobox. Thats why I have a listener on the combobox.

Now I go through the ObservableList and I check, if the date is a Monday, Thursday etc. So that works. But if I write col_RW_Montag.setCellValueFactory(new PropertyValueFactory<>("seriennr")) the column gets all serial numbers saved in the observableList, but I need the specific serial number from that specific date.

How can I get the specific serial number from the date and fill the column with it?

I hope you understand everything, because the project is in German.

Please let me know if you need further information or more code.

Thanks.

"Auftragsverteilung" class (model)

public class Auftragsverteilung {

    private Date bearbeitungsdatum;
    private Integer seriennr;

    public Auftragsverteilung(Integer seriennr, Date bearbeitungsdatum) {
        super();
        this.seriennr = seriennr;
        this.bearbeitungsdatum = bearbeitungsdatum;
    }


    public Date getBearbeitungsdatum() {
        return bearbeitungsdatum;
    }

    public void setBearbeitungsdatum(Date bearbeitungsdatum) {
        this.bearbeitungsdatum = bearbeitungsdatum;
    }


    public Integer getSeriennr() {
        return seriennr;
    }

    public void setSeriennr(Integer seriennr) {
        this.seriennr = seriennr;
    }

}

"AuftragsansichtController" class (controller)

public class RechneransichtController implements Initializable {

    @FXML
    private ComboBox<String> comboBox_RW_Wochenansicht;
    @FXML
    private TableView<Auftragsverteilung> tableRechnerWoche;
    @FXML
    private TableColumn<Auftragsverteilung, Integer> col_RW_Montag;
    @FXML
    private TableColumn<Auftragsverteilung, Integer> col_RW_Dienstag;
    @FXML
    private TableColumn<Auftragsverteilung, Integer> col_RW_Mittwoch;
    @FXML
    private TableColumn<Auftragsverteilung, Integer> col_RW_Donnerstag;
    @FXML
    private TableColumn<Auftragsverteilung, Integer> col_RW_Freitag;

    private Datenbank db = new Datenbank();

    ObservableList<Auftragsverteilung> rechnerWochenansichtTabelle = FXCollections.observableArrayList();

    public void wochenansichtFuellen() {

        // ComboBox Listener
        comboBox_RW_Wochenansicht.getSelectionModel().selectedItemProperty().addListener((options) -> {
        tableRechnerWoche.getItems().clear();

        // the week selected from the comboBox
        String wochenAuswahl = comboBox_RW_Wochenansicht.getSelectionModel().selectedItemProperty().getValue(); // DD.MM.YYYY-DD.MM.YYYY

        // String split, first date = monday, last date = friday
        String startdatum = wochenAuswahl.substring(0, 10);
        String enddatum = wochenAuswahl.substring(11, 21);


        // db = Database object with method getTasksFromWeek
        try {
            rechnerWochenansichtTabelle.addAll(db.getRechnerAusAuftragsverteilungWoche(startdatum, enddatum));
        } catch (SQLException e) {
            e.printStackTrace();
        }

        for (int i = 0; i < rechnerWochenansichtTabelle.size(); i++) {

            Date d = rechnerWochenansichtTabelle.get(i).getBearbeitungsdatum();
            Integer seriennr = rechnerWochenansichtTabelle.get(i).getSeriennr(); // SERIENNUMER DIE REIN MUSS


            switch(simpleDateformat.format(d)) {

            case "Montag":
            col_RW_Montag.setCellValueFactory(new PropertyValueFactory<>("seriennr"));
                break;
            case "Dienstag":
            col_RW_Dienstag.setCellValueFactory(new PropertyValueFactory<>("seriennr"));
                break;
            case "Mittwoch":                                                                                                                                    
            col_RW_Mittwoch.setCellValueFactory(new PropertyValueFactory<>("seriennr"));
                break;
            case "Donnerstag":
            col_RW_Donnerstag.setCellValueFactory(new PropertyValueFactory<>("seriennr"));
                break;
            case "Freitag":
            col_RW_Freitag.setCellValueFactory(new PropertyValueFactory<>("seriennr"));
                break;
            default:
            break;          
            }

        }
        tableRechnerWoche.setItems(rechnerWochenansichtTabelle);
    });

}

Upvotes: 0

Views: 2229

Answers (2)

fabian
fabian

Reputation: 82491

You want to place multiple Auftragsverteilung objects in a single row. Since every element in the items list corresponds to a single row of the table, your approach is wrong. You need to put store multiple Auftragsverteilung objects in a single item to access access the data properly or use custom cellValueFactorys, to retrieve the data and use items identifying the week.

Furthermore I do not recommend relying on the program using German weekdays unless you specifically set up simpleDateformat to use German as locale. Otherwise changing the default locale may break your progam and I wouldn't count on your professor/tutor using german locale on the machine they use to test your program.

The following code assumes you do not specify the columns in the fxml file, but create them programmatically. In the following code I use Auftragsverteilung[] storing the objects for monday, tuesday, ..., friday. Furthermore it uses the java.time API:

@Override
public void initialize​(URL location, ResourceBundle resources) {
    final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE", Locale.GERMAN);

    for (int i = 1; i <= lastDay; i++) {
        final int dayIndex = i-1;
        DayOfWeek day = DayOfWeek.of(i);
        TableColumn<Auftragsverteilung[], Integer> column = new TableColumn<>(formatter.format(day));
        column.setCellValueFactory(cd -> {
            Auftragsverteilung auftrag = cd.getValue()[dayIndex];
            return new SimpleObjectProperty<>(auftrag == null ? null : auftrag.getSeriennr());
        });
        tableRechnerWoche.getColumns().add(column);

    }

    tableRechnerWoche.setItems(rechnerWochenansichtTabelle);
    ...
}
@FXML
private TableView<Auftragsverteilung[]> tableRechnerWoche;
@FXML
private TableColumn<Auftragsverteilung[], Integer> col_RW_Montag;
@FXML
private TableColumn<Auftragsverteilung[], Integer> col_RW_Dienstag;
@FXML
private TableColumn<Auftragsverteilung[], Integer> col_RW_Mittwoch;
@FXML
private TableColumn<Auftragsverteilung[], Integer> col_RW_Donnerstag;
@FXML
private TableColumn<Auftragsverteilung[], Integer> col_RW_Freitag;

...

public void wochenansichtFuellen() {

    // ComboBox Listener (ChangeListener)
    comboBox_RW_Wochenansicht.valueProperty().addListener((o, oldValue, newValue) -> {
        rechnerWochenansichtTabelle.clear();

        // String split, first date = monday, last date = friday
        String startdatum = newValue.substring(0, 10);
        String enddatum = newValue.substring(11, 21);

        // db = Database object with method getTasksFromWeek
        try {
            // depending on the return type and order of the elements
            // rechnerWochenansichtTabelle.add(db.getRechnerAusAuftragsverteilungWoche(startdatum, enddatum));
            // may be sufficient instead of the following code

            // store each Auftragsverteilung in array with index corresponding to the day of week of the bearbeitungsdatum
            Auftragsverteilung[] row = new Auftragsverteilung[DayOfWeek.FRIDAY.getValue()];
            for (Auftragsverteilung auftrag : db.getRechnerAusAuftragsverteilungWoche(startdatum, enddatum)) {
                LocalDate date = auftrag.getBearbeitungsdatum().toLocalDate();
                row[date.getDayOfWeek().getValue() - 1] = auftrag;
            }

            rechnerWochenansichtTabelle.add(row);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    });

}

Upvotes: 1

fonZ
fonZ

Reputation: 2479

You are not using ObservableList as it should be used. Check the documentation for ObservableList. ObservableList uses the Observer pattern. There are Observers and Observables. You have a list of Observables, your controller can Observe them. https://en.wikipedia.org/wiki/Observer_pattern

Without looking at your code, you need something similar to this (below snippet copied from https://dzone.com/articles/javafx-collections-observablelist-and-observablema):

observableList.addListener(new ListChangeListener() {
    @Override
    public void onChanged(ListChangeListener.Change change) {    
        System.out.println("Detected a change! ");
        while (change.next()) {
            System.out.println("Was added? " + change.wasAdded());
            System.out.println("Was removed? " + change.wasRemoved());
        }
    }
}

Basically, the listener will observe your observables and will tell you through this overriden method what has changed and how it changed. There you need to take action, i.e. change the value in the table.

I hope this helps.

Upvotes: 0

Related Questions