JavaFx ViewList通过不同的实例共享值

时间:2017-10-02 10:50:28

标签: java listview javafx

嗨StackOverflow人,

这里的第一个问题是,我坚持使用这个代码,不能继续前进,尝试了不同的方法,但无法弄清楚为什么会这样。

代码是一些列表,每个列表代表一周中的某一天,每个列表都有可能的时间。现在,每次我运行代码时,每个列表,即使没有更新,也使用可用的最后日期。为了示例,删除几乎所有列表并仅留下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 */

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

2 个答案:

答案 0 :(得分:1)

如果我查看您的代码,我会看到以下内容:

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

这意味着两个listViewTurnosX都包含完全相同的元素引用。

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

迭代哪个列表并不重要,两者都包含相同的元素,因此在这两种情况下都会更新相同的属性。

答案 1 :(得分:1)

考虑如何创建列表:

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

您使用的工厂方法的documentation读取:

  

构造由指定列表支持的ObservableList。

即 - 提供的基本列表保留为后备(存储)列表。由于两个ObservableList实例共享相同的原始ArrayList,因此难怪他们共享内容。

您可能希望使用工厂方法FXCollections.ObservableArrayList来创建新的ObservableList(后备列表在内部创建,或者是列表本身)。

如果你真的需要非可观察列表实例,如果列表不相等,你应该使用两个不同的实例。