-1

I have a class like this:

public class HourMinute {
    private int hour;
    private int minute;
...
}

And a class like this:

public class WorkTime {
    private HourMinute start;
    private HourMinute end;
    private HourMinute total;
    private LocalDate ld;
    private int ID;
...
}

I store the WorkTime type informations in a database. How am I supposed to put the data on a table view?

public void tableColumns() {
    TableColumn year = new TableColumn("Year");
    TableColumn month = new TableColumn("Month");
    TableColumn day = new TableColumn("Day");
    TableColumn startHour = new TableColumn("Start hour");
    TableColumn startMinute = new TableColumn("Start minute");
    TableColumn endHour = new TableColumn("End hour");
    TableColumn totalHour = new TableColumn("Total hour");
    TableColumn totalMinute = new TableColumn("Total minute");

    //table.getColumns().addAll(...);
    data.addAll(db.getAllWork());
    table.setItems(data);
}

As you could see above the WorkTime class contains HourMinute and LocalDate variables. How am I supposed to extract the data from those types to make them "showable" in my tableview?

(Side question: is it possible to fill a cell with a string? Like I could make only a Data column what's gonna look like YYYY-MM-DD (year+"-"+month+"-"+day))

Stekike29
  • 1
  • 1
  • make a getter returning a SimpleStringProperty containing your HourMinute display format. – Reda Meskali Aug 05 '18 at 19:21
  • Well, sounds good, does not work. How am I supposed to call a getter method in the following code: startHour.setCellValueFactory(new PropertyValueFactory<>("start")); – Stekike29 Aug 05 '18 at 19:23
  • See my answer here: https://stackoverflow.com/questions/50670743/javafx-tableview-not-showing-data/50671591#50671591 It will walk you through the steps needed to have your object data displayed in a TableView. – Zephyr Aug 05 '18 at 19:23
  • Possible duplicate of [Javafx TableView not showing data](https://stackoverflow.com/questions/50670743/javafx-tableview-not-showing-data) – Zephyr Aug 05 '18 at 19:24
  • Well, your comment is perfect if I'd have Strings, but I have HourTime data type that contains 2 intand LocalDate what contains 3 int. I would like an example code using my data types. – Stekike29 Aug 05 '18 at 19:29
  • The data type doesn't matter; you would handle them the same. But I'll get a quick example together. – Zephyr Aug 05 '18 at 19:38
  • Thank you very much! I am the type who learns something the best if see a viable example – Stekike29 Aug 05 '18 at 19:40
  • Your data structure is more complicated than it needs to be, though and you'll need to break it down a bit more. – Zephyr Aug 05 '18 at 19:45
  • I can put the code I have on github if it is easier for you. But also I can rethink my project on the way you show the example as long as it shows the data in tableview :) – Stekike29 Aug 05 '18 at 19:48
  • still not learned to provide a [mcve] ? Code snippets simply don't help (except somebody is really really keen on helping you such as @Zephyr ;) btw, the info tab of the javafx tag has a couple of references to tutorials and common problems ... – kleopatra Aug 06 '18 at 07:40
  • Possible duplicate of [Javafx tableview not showing data in all columns](https://stackoverflow.com/questions/18971109/javafx-tableview-not-showing-data-in-all-columns) – kleopatra Aug 06 '18 at 07:42

1 Answers1

0

You need to update your data object model to represent the data you want displayed in the TableView. So in the code below, I've modified your WorkTime class to be more suited to display.

So for your WorkTime class, I've updated each field to a Property so the TableView can find it.

I refactored the WorkTime class a bit as well. The constructor now accepts the HourMinute objects and parses the data from those when creating the WorkTime object.

public class WorkTime {

    // All fields should be converted to properties
    private IntegerProperty startHour = new SimpleIntegerProperty();
    private IntegerProperty startMinute = new SimpleIntegerProperty();
    private IntegerProperty endHour = new SimpleIntegerProperty();
    private IntegerProperty endMinute = new SimpleIntegerProperty();
    private IntegerProperty totalHours = new SimpleIntegerProperty();
    private IntegerProperty totalMinutes = new SimpleIntegerProperty();
    private ObjectProperty<LocalDate> localDate = new SimpleObjectProperty<>();

    public WorkTime(HourMinute start, HourMinute end, HourMinute total, LocalDate localDate) {
        // Accept the start and end times as HourMinute objects and extract each value from them.
        this.startHour.set(start.getHour());
        this.startMinute.set(start.getMinute());
        this.endHour.set(end.getHour());
        this.endMinute.set(end.getMinute());
        this.totalHours.set(total.getHour());
        this.totalMinutes.set(total.getMinute());
        this.localDate.set(localDate);
    }

    public int getStartHour() {
        return startHour.get();
    }

    public IntegerProperty startHourProperty() {
        return startHour;
    }

    public int getStartMinute() {
        return startMinute.get();
    }

    public IntegerProperty startMinuteProperty() {
        return startMinute;
    }

    public int getEndHour() {
        return endHour.get();
    }

    public IntegerProperty endHourProperty() {
        return endHour;
    }

    public int getEndMinute() {
        return endMinute.get();
    }

    public IntegerProperty endMinuteProperty() {
        return endMinute;
    }

    public int getTotalHours() {
        return totalHours.get();
    }

    public IntegerProperty totalHoursProperty() {
        return totalHours;
    }

    public int getTotalMinutes() {
        return totalMinutes.get();
    }

    public IntegerProperty totalMinutesProperty() {
        return totalMinutes;
    }

    public LocalDate getLocalDate() {
        return localDate.get();
    }

    public ObjectProperty<LocalDate> localDateProperty() {
        return localDate;
    }
}

Now, back in your main class, you need to update your TableView definition to define what type of data it is going to hold. In this case, it is set to display a list of WorkTime objects:

TableView<WorkTime> tableView = new TableView<>();

The TableColumn objects also need to be updated to define what data type to display. This will take two parameters: the overall object type, and the data type the cell will hold:

TableColumn<WorkTime, Integer> colStartHour = new TableColumn<>("Start Hour");
        TableColumn<WorkTime, String> colStartMinute = new TableColumn<>("Start Minute");
        TableColumn<WorkTime, Integer> colEndHour = new TableColumn<>("End Hour");
        TableColumn<WorkTime, String> colEndMinute = new TableColumn<>("End Minute");
        TableColumn<WorkTime, Integer> colTotalHours = new TableColumn<>("Total Hours");
        TableColumn<WorkTime, String> colTotalMinutes = new TableColumn<>("Total Minutes");

The last step is to define the CellValueProperty for each column. This is where you tell JavaFX exactly where in your WorkTime class it will find the data:

colStartHour.setCellValueFactory(new PropertyValueFactory<>("startHour"));
        colStartMinute.setCellValueFactory(new PropertyValueFactory<>("startMinute"));
        colEndHour.setCellValueFactory(new PropertyValueFactory<>("endHour"));
        colEndMinute.setCellValueFactory(new PropertyValueFactory<>("endMinute"));
        colTotalHours.setCellValueFactory(new PropertyValueFactory<>("totalHours"));
        colTotalMinutes.setCellValueFactory(new PropertyValueFactory<>("totalMinutes"));

You'll see the new PropertyValueFactory<>("propertyName") section defines the name of the property defined in WorkTime. JavaFX will get the value of that property, and display it in the cell.

So this works will any datatype you need, as long as you defined the column to expect that datatype.

That is all there is to it! This will now allow you to display the data properly.

Below is a simple MCVE that uses the WorkTime class above.

import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableArray;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.time.LocalDate;
import java.util.List;

public class Main extends Application {

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

    @Override
    public void start(Stage primaryStage) {

        // Create sample WorkTime objects. Store them in an ObservableArrayList so the TableView can display them
        ObservableList<WorkTime> workTimes = FXCollections.observableArrayList();
        workTimes.add(new WorkTime(
                new HourMinute(1, 2),
                new HourMinute(1, 2),
                new HourMinute(1, 2),
                LocalDate.now()));
        workTimes.add(new WorkTime(
                new HourMinute(1, 2),
                new HourMinute(1, 2),
                new HourMinute(1, 2),
                LocalDate.now()));
        workTimes.add(new WorkTime(
                new HourMinute(1, 2),
                new HourMinute(1, 2),
                new HourMinute(1, 2),
                LocalDate.now()));

        // Simple UI
        VBox root = new VBox(10);
        root.setPadding(new Insets(10));
        root.setAlignment(Pos.TOP_CENTER);

        // Create a TableView
        TableView<WorkTime> tableView = new TableView<>();

        // Create each column
        TableColumn<WorkTime, Integer> colStartHour = new TableColumn<>("Start Hour");
        TableColumn<WorkTime, String> colStartMinute = new TableColumn<>("Start Minute");
        TableColumn<WorkTime, Integer> colEndHour = new TableColumn<>("End Hour");
        TableColumn<WorkTime, String> colEndMinute = new TableColumn<>("End Minute");
        TableColumn<WorkTime, Integer> colTotalHours = new TableColumn<>("Total Hours");
        TableColumn<WorkTime, String> colTotalMinutes = new TableColumn<>("Total Minutes");

        // Set the CellValueFactory for each column to define what data to use for each column. This should match the
        // property set in the WorkTime class
        colStartHour.setCellValueFactory(new PropertyValueFactory<>("startHour"));
        colStartMinute.setCellValueFactory(new PropertyValueFactory<>("startMinute"));
        colEndHour.setCellValueFactory(new PropertyValueFactory<>("endHour"));
        colEndMinute.setCellValueFactory(new PropertyValueFactory<>("endMinute"));
        colTotalHours.setCellValueFactory(new PropertyValueFactory<>("totalHours"));
        colTotalMinutes.setCellValueFactory(new PropertyValueFactory<>("totalMinutes"));

        // Add the columns to the TableView
        tableView.getColumns().addAll(colStartHour, colStartMinute, colEndHour, colEndMinute, colTotalHours, colTotalMinutes);

        // Set the people list as the data for the TableView
        tableView.setItems(workTimes);

        // Add the TableView to the scene
        root.getChildren().add(tableView);

        // Finish building the stage and show it
        primaryStage.setTitle("TableView Sample");
        primaryStage.setScene(new Scene(root));
        primaryStage.show();

    }
}

Answer to your side question

This is simple to do as well. Just add another property to your WorkTime class:

private StringProperty dateString = new SimpleStringProperty();

public String getDateString() {
    return year + "-" + month + "-" + date;
}

Then add the column to your TableView and set the appropriate CelLValueProperty.

Zephyr
  • 9,885
  • 4
  • 28
  • 63
  • Thank you. It is gonna be much easier to understand now. – Stekike29 Aug 05 '18 at 20:10
  • to the aside: never ever do any manual formatting of a date, instead use an appropriate DateTimeFormatter - otherwise, you come into hell if the Locale changes – kleopatra Aug 07 '18 at 08:37