【问题标题】:How to add a DatePicker to Tableview with a DatePickerCell如何使用 DatePickerCell 将 DatePicker 添加到 Tableview
【发布时间】:2013-11-20 08:50:33
【问题描述】:

我已将 DatePicker 添加到具有以下类的 TableView 中:https://code.google.com/p/javafx-filterable-table-columns/source/browse/src/main/java/thirdparty/eu/schudt/javafx/controls/calendar/DatePicker.java?r=db47db237b3342712aafb693f392d403455d5299

我使用 DatePickerCell 类来覆盖 TableCell。 DatePicker 在 TableView 中显示良好。但是updateItem方法效果不好,它不会更新ObservableList。

我在这里缺少什么?任何人都可以面临同样的问题吗?

这是我的代码:

import java.text.SimpleDateFormat;  
import java.util.Locale;  
import javafx.beans.value.ObservableValue;  
import javafx.geometry.Pos;  
import javafx.scene.control.TableCell;  
import thirdparty.eu.schudt.javafx.controls.calendar.DatePicker;  

public class DatePickerCell<S, T> extends TableCell<S, T> {  

    private final DatePicker datePicker;  
    private ObservableValue<T> ov;  
    public DatePickerCell() {  
        // Initialize the DatePicker for birthday  
        this.datePicker = new DatePicker(Locale.ENGLISH);  
        this.datePicker.setDateFormat(new SimpleDateFormat("dd/MM/yyyy"));  
        this.datePicker.getCalendarView().todayButtonTextProperty().set("Today");  
        this.datePicker.getCalendarView().setShowWeeks(false);          
        this.datePicker.getStylesheets().add("styles/DatePicker.css");  
        this.setAlignment(Pos.CENTER);  
        this.setGraphic(this.datePicker);  
    }  
    @Override  
    public void updateItem(T item, boolean empty) {  
        super.updateItem(item, empty);  
        setGraphic(this.datePicker);  
    }  
}

以及 FXController 代码中 cellFactory 的部分:

@FXML  
private TableColumn revueDateCol;  

this.revueDateCol.setCellFactory(new Callback<TableColumn<Revue, Date>, TableCell<Revue, Date>>() {  
        @Override  
        public TableCell<Revue, Date> call(TableColumn<Revue, Date> arg0) {  
            return new DatePickerCell<>();  
        }  
   });

感谢您的帮助。


我尝试过以这种方式实现,但是当我滚动时,单元格会返回到原始值。 有什么想法吗?

public class DatePickerCell<S, T> extends TableCell<Revue, Date> {

    private DatePicker datePicker;

    public DatePickerCell() {
        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);

        if (empty) {
            setText(null);
            setGraphic(null);
        } else {
        if (datePicker != null) {
               datePicker.setSelectedDate(getDate());
        }

            setGraphic(this.datePicker);
            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
        }
    }

    private void createDatePicker() {
        datePicker = new DatePicker(Locale.FRENCH);
        DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
        datePicker.setDateFormat(formatter);
        datePicker.setPromptText("jj/mm/aaaa");
        datePicker.getCalendarView().todayButtonTextProperty().set("Aujourd'hui");
        datePicker.getCalendarView().setShowWeeks(false);
        datePicker.getStylesheets().add("/styles/datePicker.css");

        datePicker.selectedDateProperty().addListener(
                new ChangeListener<Date>() {
                    @Override
                    public void changed(ObservableValue<? extends Date> observable,
                            Date oldValue, Date newValue) {

                        commitEdit(newValue);
                    }
                });

        setAlignment(Pos.CENTER);
    }

    private Date getDate() {
        return datePicker.getSelectedDate() != null ? datePicker.getSelectedDate() : getItem();
    }

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

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

}

问候,

【问题讨论】:

    标签: datepicker javafx-2 javafx tableview


    【解决方案1】:

    这是一个可行的解决方案。它使用 Java 8 的 DatePicker 和 TableView 控件。 博文可通过here 获取。

    import java.text.SimpleDateFormat;
    import java.time.LocalDate;
    import java.util.Calendar;
    import java.util.Date;
    import javafx.application.Platform;
    import javafx.collections.ObservableList;
    import javafx.event.Event;
    import javafx.event.EventHandler;
    import javafx.geometry.Pos;
    import javafx.scene.control.ContentDisplay;
    import javafx.scene.control.DatePicker;
    import javafx.scene.control.TableCell;
    
    public class DatePickerCell<S, T> extends TableCell<BirthdayEvent, Date> {
    
        private DatePicker datePicker;
        private ObservableList<BirthdayEvent> birthdayData;
    
        public DatePickerCell(ObservableList<BirthdayEvent> listBirthdays) {
    
            super();
    
            this.birthdayData = listBirthdays;
    
            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 (null == this.datePicker) {
                System.out.println("datePicker is NULL");
            }
    
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
    
                if (isEditing()) {
                    setContentDisplay(ContentDisplay.TEXT_ONLY);
    
                } else {
                    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("jj/mm/aaaa");
            datePicker.setEditable(true);
    
            datePicker.setOnAction(new EventHandler() {
                public void handle(Event t) {
                    LocalDate date = datePicker.getValue();
                    int index = getIndex();
    
                    SimpleDateFormat smp = new SimpleDateFormat("dd/MM/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());
    
                    if (null != getBirthdayData()) {
                        getBirthdayData().get(index).setDate(cal.getTime());
                    }
                }
            });
    
            setAlignment(Pos.CENTER);
        }
    
        @Override
        public void startEdit() {
            super.startEdit();
        }
    
        @Override
        public void cancelEdit() {
            super.cancelEdit();
            setContentDisplay(ContentDisplay.TEXT_ONLY);
        }
    
        public ObservableList<BirthdayEvent> getBirthdayData() {
            return birthdayData;
        }
    
        public void setBirthdayData(ObservableList<BirthdayEvent> birthdayData) {
            this.birthdayData = birthdayData;
        }
    
        public DatePicker getDatePicker() {
            return datePicker;
        }
    
        public void setDatePicker(DatePicker datePicker) {
            this.datePicker = datePicker;
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      要使 tableView 可编辑,您需要
      tableView.setEditable(true)。
      覆盖TableCell的startEdit()、cancelEdit()方法。
      设置相关TableColumn的revueDateCol.setOnEditCommit()。
      编辑完成后调用commitEdit()。

      工作示例是official tutorial for Table View,示例 12-11:单元格编辑的替代解决方案。
      上面的前三个步骤几乎相同,只是您将使用 DatePicker 而不是 TextField。
      最后一步可以是:

      private void createTextField() {
          datePicker = new DatePicker(Locale.ENGLISH);
          datePicker.setDateFormat(new SimpleDateFormat("dd/MM/yyyy"));
          datePicker.getCalendarView().todayButtonTextProperty().set("Today");
          datePicker.getCalendarView().setShowWeeks(false);
          datePicker.getStylesheets().add("styles/DatePicker.css");
          datePicker.selectedDateProperty().addListener(new ChangeListener<Date>() {
              @Override
              public void changed(ObservableValue<? extends Date> observable, Date oldValue, Date newValue) {
                  commitEdit(newValue);
              }
          });
      }
      

      【讨论】:

        猜你喜欢
        • 2011-01-02
        • 1970-01-01
        • 2021-10-25
        • 1970-01-01
        • 1970-01-01
        • 2023-03-06
        • 1970-01-01
        • 2014-12-23
        相关资源
        最近更新 更多