gpt4 book ai didi

java - 尝试制作自定义控件,需要在值发生更改时发出通知

转载 作者:行者123 更新时间:2023-12-01 13:10:42 24 4
gpt4 key购买 nike

我有一个 DatePicker,来自 javafx 导入。但是我需要它包含 Calendar 属性,这就是为什么我制作了一个扩展 DatePicker 的自定义控件。

但是,每次更改日期选择器时,它都应该调用此属性,这就是为什么我认为在执行 onAction 事件时必须使用 .notify 方法。这会引发 java.lang.IllegalMonitorStateException 异常。

这是我用于此自定义控件的代码:

public class DatePickerControl extends DatePicker
{
private ObjectProperty<Calendar> calendar;

public DatePickerControl() {
super();
setValue(LocalDate.now());
}

/**
* Get the value of calendar
*
* @return the value of calendar
*/
public ObjectProperty<Calendar> calendarProperty() {
Calendar calendar = new GregorianCalendar();
System.out.println("test");
calendar.set(getValue().getYear(), getValue().getMonthValue(), getValue().getDayOfMonth());
return new SimpleObjectProperty<>(calendar);
}

/**
* Set the value of calendar
*
* @param calendar new value of calendar
*/
public void setCalendar(Calendar calendar) {
this.calendar.set(calendar);
LocalDate ld = LocalDate.now();
ld.withYear(calendar.get(Calendar.YEAR));
ld.withMonth(calendar.get(Calendar.MONTH));
ld.withDayOfMonth(calendar.get(Calendar.DAY_OF_MONTH));
setValue(ld);
}

public Calendar getCalendar() {
return calendar.get();
}
}

以及我调用 .notify() 的地方:

dpAgendaRange.setOnAction(new EventHandler<ActionEvent>() {

@Override
public void handle(ActionEvent t) {
t.notify();
}
});

我是 JavaFX 新手,所以如果代码不是很结构化,我深表歉意。

最佳答案

首先,notify()不做你认为它做的事。它是低级并发 API 的一部分,负责唤醒处于 wait() 阻塞状态的线程。您可以阅读此内容 here尽管这与您想要做的事情无关。

我认为您想要做的是拥有 ObjectProperty<Calendar>它始终与 DatePicker 中的日期值匹配的valueProperty .

为此,只需定义 ObjectProperty<Calendar>以通常的方式:即仅创建一次,并有 setCalendar(...)设置其值的方法,a getCalendar()获取其值的方法,以及 calendarProperty()返回属性本身的方法。

维持 ObjectProperty<Calendar> 之间的绑定(bind)和 valueProperty DatePicker的,只需为每个监听器注册一个监听器,并在其中一个发生更改时更新另一个监听器。

(另请注意,LocalDate 和 Calendar 之间的月份编号不同。)

所以像这样:

public class DatePickerControl extends DatePicker {
private ObjectProperty<Calendar> calendar;

private DateTimeFormatter dateFormatter = DateTimeFormatter.ISO_DATE ;
private Format calendarFormatter = DateFormat.getDateInstance();

public DatePickerControl() {
super();
setValue(LocalDate.now());
calendar = new SimpleObjectProperty<Calendar>(Calendar.getInstance());

calendar.addListener((obs, oldValue, newValue) -> {
System.out.println("calendar changed from "+calendarFormatter.format(oldValue.getTime())+" to "+calendarFormatter.format(newValue.getTime()));
LocalDate localDate = LocalDate.now()
.withYear(newValue.get(Calendar.YEAR))
.withMonth(newValue.get(Calendar.MONTH)+1)
.withDayOfMonth(newValue.get(Calendar.DAY_OF_MONTH));
setValue(localDate);
});

valueProperty().addListener((obs, oldValue, newValue) -> {
System.out.println("Value changed from "+dateFormatter.format(oldValue)+" to "+dateFormatter.format(newValue));
Calendar cal = Calendar.getInstance();
cal.set(getValue().getYear(), getValue().getMonthValue()-1, getValue().getDayOfMonth());
calendar.set(cal);
});
}


public ObjectProperty<Calendar> calendarProperty() {
return calendar;
}

public void setCalendar(Calendar calendar) {
this.calendar.set(calendar);
}

public Calendar getCalendar() {
return calendar.get();
}
}

一个简单的测试:

import java.text.DateFormat;

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;


public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
VBox root = new VBox();
Scene scene = new Scene(root,400,400);

DatePickerControl datePicker = new DatePickerControl();
Label label = new Label();
final DateFormat calFormatter = DateFormat.getDateInstance() ;
datePicker.calendarProperty().addListener((obs, oldValue, newValue) -> label.setText(calFormatter.format(newValue.getTime())));
root.getChildren().addAll(datePicker, label);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}

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

关于java - 尝试制作自定义控件,需要在值发生更改时发出通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22892018/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com