JavaFx View 列表与不同实例共享值

标签 java listview javafx

StackOverflow 的 friend 们大家好,

这里的第一个问题,我被困在这段代码上,无法继续前进,尝试了不同的方法,但无法弄清楚为什么会发生这种情况。

该代码旨在成为几个列表,每个列表代表一周中的一天,并且每个列表都有所有可能的时间。现在,每次我运行代码时,每个列表(即使没有更新)也会使用最后可用的日期。出于示例目的,删除几乎所有列表,仅保留 2 个。

日期的更新正在此行上完成,t1.setFecha(lunesDate.plusDays(i));,但如果例如,我删除此行在其中一个列表上的行中,该列表正在更新日期,即使这发生在另一个列表上,还有另一个变量!这就像 JVM 认为所有列表都是相同的...对我来说毫无意义...

谁能指出代码的问题出在哪里吗?

Turno.class 类

import java.time.LocalDate;

import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;

public class Turno {

private static final int LIBRE = 1;
private static final int RESERVADO = 2;
private static final int CUMPLIDO = 3;
private static final int CERRADO = 4;

private SimpleIntegerProperty id = new SimpleIntegerProperty();
private SimpleObjectProperty<LocalDate> fecha = new SimpleObjectProperty<LocalDate>();
private SimpleIntegerProperty idhorario = new SimpleIntegerProperty();
private SimpleStringProperty horario = new SimpleStringProperty();
private SimpleIntegerProperty estado = new SimpleIntegerProperty();
private SimpleIntegerProperty idProfesional = new SimpleIntegerProperty();
private SimpleStringProperty profesional = new SimpleStringProperty();;
private SimpleIntegerProperty idPaciente = new SimpleIntegerProperty();
private SimpleStringProperty paciente = new SimpleStringProperty();;
private SimpleStringProperty observaciones = new SimpleStringProperty();;

public Turno(int id, LocalDate d, int idh, String h, int e, int idpro, String pro, int idpac, String pac,
String o) {
this.setId(id);
this.setFecha(d);
this.setIdHorario(idh);
this.setHorario(h);
this.setEstado(e);
this.setIdProfesional(idpro);
this.setProfesional(pro);
this.setIdPaciente(idpac);
this.setPaciente(pac);
this.setObservaciones(o);
}

public Turno() {
}

// ID
public final SimpleIntegerProperty idProperty() {
return this.id;
}

public final int getId() {
return this.idProperty().get();
}

public final void setId(final int i) {
this.idProperty().set(i);
}

/* Bunch of getter and setters for properties, just like the one above */

类 TestTurno.class

public class TestTurnos extends Application {

private static Turno turnoSeleccionado = null;

ScrollPane scrollPane = new ScrollPane();
HBox listas = new HBox();
VBox vBoxL = new VBox();
VBox vBoxM = new VBox();
ListView<Turno> listViewTurnosL = new ListView<>();
ListView<Turno> listViewTurnosM = new ListView<>();
List<Turno> listaHorarios = new ArrayList<>();
List<Turno> listaTurnos = new ArrayList<>();

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

@Override
public void start(Stage escenario) throws Exception {

// Here we get the current Monday date, in order to prepare for the current week
LocalDate lunesDate = null;
LocalDate diaSemana = null;
LocalDate diaHoy = LocalDate.now();
int d = diaHoy.getDayOfWeek().getValue();
lunesDate = diaHoy.minusDays(d - 1);

// Give the schedules to each day list
listViewTurnosL.setItems(FXCollections.observableList(listaHorarios));
listViewTurnosM.setItems(FXCollections.observableList(listaHorarios));

// Then we look for more data on the DB, 
for (int i = 0; i < 2; i++) {
    // Database magic happens here, we filled the listaTurnos, not relevant


    // We make the lists
    //
    //!!! Here is where the glitch appears, debugging shows that it only gets into the switch on the right conditions, 
    // but it keeps on updating the date on any of the lists, even when it is updating another list
    switch (i) {
    case 0: {
        for (Turno t1 : listViewTurnosL.getItems()) {
            t1.setFecha(lunesDate.plusDays(i));
        }
        // Value of t1.getFecha() is 1
        break;
    }
    case 1: {
        for (Turno t2 : listViewTurnosM.getItems()) {
            t2.setFecha(lunesDate.plusDays(i));
        }
        // Value of t1.getFecha() is 2 !!!!! 
        // Value of t2.getFecha() is 2 
        break;
        }
    }
}


vBoxL.getChildren().addAll(listViewTurnosL);
vBoxM.getChildren().addAll(listViewTurnosM);

listas.getChildren().addAll(vBoxL, vBoxM);

scrollPane.setContent(listas);
Scene escena = new Scene(scrollPane, 800, 800);
escenario.setScene(escena);
escenario.show();
}
}

最佳答案

考虑如何创建列表:

listViewTurnosL.setItems(FXCollections.observableList(listaHorarios));
listViewTurnosM.setItems(FXCollections.observableList(listaHorarios));

documentation对于您正在使用的工厂方法:

Constructs an ObservableList that is backed by the specified list.

也就是说 - 提供的基本列表保留为后备(存储)列表。由于两个 ObservableList 实例共享相同的原始 ArrayList,因此它们共享内容也就不足为奇了。

您可能想使用工厂方法FXCollections.ObservableArrayList它创建一个新的 ObservableList(支持列表是内部创建的,或者是列表本身)。

如果您确实需要不可观察的列表实例,并且列表不相等,则可能应该使用两个不同的实例。

关于JavaFx View 列表与不同实例共享值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46524101/

相关文章:

java - gradle WriteProperties任务不会创建属性文件,除非直接运行该任务

Java:更改方法参数的最有效方法

java - Android Studio。 Activity 更改后的屏幕轻弹

delphi - 将所有选定的项目从 ListView 复制到 ListView 2

java - 在我的例子中如何使用 javaFX Task - 不重复

javafx - 我在哪里为 JavaFX 提交错误?

java - 创建我自己的基于文本的数据存储

delphi - 如何使 ListView 在中心显示特定项目?

C# 检查所有 ListView 组中除第一个之外的所有项目

java - 映射后加载 fxml 时,spring 出现 javafx 应用程序异常