【问题标题】:JavaFX: TableView fill column with specific data from ObservableListJavaFX:TableView 使用 ObservableList 中的特定数据填充列
【发布时间】:2023-03-09 21:12:01
【问题描述】:

我在大学的一个项目中工作。我刚刚学习了 Java 和 JavaFX。

我有一个问题,也许有人可以帮助我。

使用这个小软件,您可以计划一周的任务。在表格视图中,您有从星期一到星期五的列。

我有一个数据库,我可以在其中获取对象“Auftragsverteilung”(这意味着计划在特定日期执行的任务)。这些对象有一个序列号 (= seriennr) 和一个日期 (= bearbeitungsdatum)。

为了在 tableview 中填满一周,我从数据库中获取了本周计划的所有任务。一周的任务保存在 ObservableList rechnerWochenansichtTabelle 中。 您可以从组合框中选择星期。这就是为什么我在组合框上有一个监听器。

现在我检查 ObservableList 并检查日期是否是星期一、星期四等。 所以这行得通。但是如果我写 col_RW_Montag.setCellValueFactory(new PropertyValueFactory("seriennr")) 该列会获取保存在 observableList 中的所有序列号,但我需要该特定日期的特定序列号。

如何从日期中获取具体的序列号并填入列中?

我希望你明白一切,因为这个项目是德语的。

如果您需要更多信息或更多代码,请告诉我。

谢谢。

“Auftragsverteilung”类(模型)

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”类(控制器)

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);
    });

}

【问题讨论】:

  • 用英文创建一个小的工作示例。请参阅:How to create a Minimal, Complete, and Verifiable example。
  • 与您的问题无关:请学习 java 命名约定并遵守它们。还有一个提示:不要在名称中混用语言,很快,你会混淆所有同事,包括你自己 :) 基本的英语词汇并不难学..
  • 相关:您的 switch 语句实际上什么都不做 - 它总是设置相同的 valueFactory。最好退后一步,学习一些 fx 基础知识,尤其是那些与 tableView 相关的..
  • 您不应该使用循环来设置每一列的 cellValueFactory。将每一列的 cellValueFactory 设置一次。

标签: java javafx observablelist


【解决方案1】:

您想将多个 Auftragsverteilung 对象放在一行中。由于items 列表中的每个元素都对应于表格的一行,因此您的方法是错误的。您需要将多个 Auftragsverteilung 对象存储在单个项目中以正确访问访问数据或使用自定义 cellValueFactorys 来检索数据并使用标识周的项目。

此外,除非您专门设置 simpleDateformat 以使用德语作为语言环境,否则我不建议您依赖使用德语工作日的程序。否则更改默认语言环境可能会破坏你的程序,我不会指望你的教授/导师在他们用来测试你的程序的机器上使用德语语言环境。

以下代码假定您没有指定 fxml 文件中的列,而是以编程方式创建它们。在下面的代码中,我使用Auftragsverteilung[] 存储周一、周二、...、周五的对象。此外,它使用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();
        }
    });

}

【讨论】:

    【解决方案2】:

    您没有使用 ObservableList,因为它应该被使用。检查 ObservableList 的文档。 ObservableList 使用观察者模式。有观察者和可观察者。你有一个 Observables 列表,你的控制器可以观察它们。 https://en.wikipedia.org/wiki/Observer_pattern

    不看你的代码,你需要类似的东西(下面是从https://dzone.com/articles/javafx-collections-observablelist-and-observablema复制的sn-p):

    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());
            }
        }
    }
    

    基本上,监听器会观察你的 observables,并通过这个被覆盖的方法告诉你发生了什么变化以及它是如何变化的。在那里您需要采取行动,即更改表中的值。

    我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2013-06-27
      • 2013-10-27
      • 1970-01-01
      • 2012-02-27
      • 2017-08-07
      • 2020-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多