tableview刷新问题

时间:2015-03-12 07:31:51

标签: java datepicker tableview javafx-8

我有一个包含三列开始日期,结束日期和否的表视图。天。 我想要一个功能,当我从datepicker选择开始日期时,基于否。该行中的天数,应计算结束日期,并应显示在表格视图中。 我在开始日期使用以下日期选择器类来实现上述功能。

    package upgradeworkbench.Helper;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.event.Event;
import javafx.geometry.Pos;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableView;


public class DatePickerProjectInputStart<S, T> extends TableCell<ProjectPlanInput, Date> {

    private DatePicker datePicker;
    private ObservableList<ProjectPlanInput> Data;
    private TableView<ProjectPlanInput> ProjectInputTable;
    public DatePickerProjectInputStart(ObservableList<ProjectPlanInput> listBirthdays,TableView table) {

        super();

        this.Data = listBirthdays;
        this.ProjectInputTable=table;
        if (datePicker == null) {
            createDatePicker();
        }
        setGraphic(datePicker);
        setContentDisplay(ContentDisplay.GRAPHIC_ONLY);

        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                datePicker.requestFocus();
            }
        });


    }

     @Override
        public void updateItem(Date item, boolean empty) {
            super.updateItem(item, empty);
            SimpleDateFormat smp = new SimpleDateFormat("dd-MM-yyyy");

            if (empty) {
                setText(null);
                setGraphic(null);
            } 

            else {
                if(item!=null)
                {
                setDatepikerDate(smp.format(item));
                setText(smp.format(item));
                }
                setGraphic(this.datePicker);
                setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            }
        }

    private void setDatepikerDate(String dateAsStr) {

        LocalDate ld = null;
        int jour, mois, annee;

        jour = mois = annee = 0;
        try {
            jour = Integer.parseInt(dateAsStr.substring(0, 2));
            mois = Integer.parseInt(dateAsStr.substring(3, 5));
            annee = Integer.parseInt(dateAsStr.substring(6, dateAsStr.length()));
        } catch (NumberFormatException e) {
            System.out.println("setDatepikerDate / unexpected error " + e);
        }

        ld = LocalDate.of(annee, mois, jour);
        datePicker.setValue(ld);
    }

    private void createDatePicker() {
        this.datePicker = new DatePicker();
        datePicker.setPromptText("dd-mm-yyyy");
        datePicker.setEditable(false);

        datePicker.setOnAction(new EventHandler() {
            public void handle(Event t) {
                LocalDate date = datePicker.getValue();
                int index = getIndex();
                Date changed_date = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
                SimpleDateFormat smp = new SimpleDateFormat("DD/MMM/YYYY");
                Calendar cal = Calendar.getInstance();
                cal.set(Calendar.DAY_OF_MONTH, date.getDayOfMonth());
                cal.set(Calendar.MONTH, date.getMonthValue() - 1);
                cal.set(Calendar.YEAR, date.getYear());

                setText(smp.format(cal.getTime()));
                  commitEdit(cal.getTime());
                 ProjectInputTable.getItems().get(getIndex()).setStartDate(changed_date);
                Date strtDate = changed_date;
                int weekdays = Integer.valueOf(ProjectInputTable.getItems().get(getIndex()).getEstimate());
                        Calendar cald = Calendar.getInstance();
                        cald.setTime(strtDate);
                        int originalDayOfWeek = cald.get(Calendar.DAY_OF_WEEK);
                        int numWeeks = weekdays / 5;
                        int remainderDays = weekdays % 5;
                        cald.add(Calendar.DAY_OF_MONTH, numWeeks * 7 + remainderDays);

                        int adjustmentDays = 0;
                        if (originalDayOfWeek == Calendar.SUNDAY) {
                            adjustmentDays = 1;
                        } else if (originalDayOfWeek + remainderDays > Calendar.FRIDAY) {
                            adjustmentDays = 2;
                        }
                        cald.add(Calendar.DAY_OF_MONTH, adjustmentDays);
                        Date EndDate = cald.getTime();

                  ProjectInputTable.getItems().get(getIndex()).setEndDate(EndDate);  
                  ProjectInputTable.getColumns().get(0).setVisible(false);
                  ProjectInputTable.getColumns().get(0).setVisible(true);
                if (null != getData()) {
                    getData().get(index).setStartDate(cal.getTime());
                    getData().get(index).setEndDate(EndDate);
                }

            }
        });

        setAlignment(Pos.CENTER);
    }

    @Override
    public void startEdit() {
        super.startEdit();
    }

    @Override
    public void cancelEdit() {
        super.cancelEdit();
        setContentDisplay(ContentDisplay.TEXT_ONLY);
    }

    public ObservableList<ProjectPlanInput> getData() {
        return Data;
    }

    public void setData(ObservableList<ProjectPlanInput> Data) {
        this.Data = Data;
    }

    public DatePicker getDatePicker() {
        return datePicker;
    }

    public void setDatePicker(DatePicker datePicker) {
        this.datePicker = datePicker;
    }

private LocalDate getDate() {
            return getItem() == null ? LocalDate.now() : getItem().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        }
    }

我在使用此代码时面临的问题是,每当我选择任何行的开始日期时,也会显示其他行的开始日期。因为我正在使用表视图,并且我的两个列都有datepicker。因此,如果我想根据开始日期设置结束日期,只有当我刷新我的表时才能看到结束日期。刷新我面临上述问题。 我正在使用以下代码来刷新我的tableview。

ProjectInputTable.getColumns().get(0).setVisible(false);
ProjectInputTable.getColumns().get(0).setVisible(true);

As can be seen in the image, 3rd row start date automatically appears on entering 1st row start date

请指导如何解决此问题。

1 个答案:

答案 0 :(得分:0)

changeListener上的简单startDate可以为您带来魔力。您很可能会从TableRow中公开datepickers valueProperty并绑定它们的值。

这是一个关于如何实现绑定的非常简单的例子。

public class DatePickerDemo extends Application {

    private Stage stage;
    private DatePicker startDate;
    private DatePicker endDate;
    private int estimatedDays=10;

    public static void main(String[] args) {
        Locale.setDefault(Locale.US);
        launch(args);
    }

    @Override
    public void start(Stage stage) {
        this.stage = stage;
        stage.setTitle("DatePickerSample ");
        initUI();
        stage.show();
    }

    private void initUI() {
        VBox vbox = new VBox(20);
        vbox.setStyle("-fx-padding: 10;");
        Scene scene = new Scene(vbox, 400, 400);
        stage.setScene(scene);

        startDate = new DatePicker();
        endDate = new DatePicker();

        GridPane gridPane = new GridPane();
        gridPane.setHgap(10);
        gridPane.setVgap(10);

        Label checkInlabel = new Label("Start Date:");
        gridPane.add(checkInlabel, 0, 0);

        GridPane.setHalignment(checkInlabel, HPos.LEFT);
        gridPane.add(startDate, 0, 1);

        Label checkOutlabel = new Label("End Date:");
        gridPane.add(checkOutlabel, 1, 0);

        GridPane.setHalignment(checkOutlabel, HPos.LEFT);
        gridPane.add(endDate, 1, 1);

        startDate.valueProperty().addListener((ob, ov, nv) -> {
            if(nv!=null){
                endDate.setValue(nv.plusDays(estimatedDays));
            }
        });
        vbox.getChildren().add(gridPane);
    }
}