在 JavaFX 的 DatePicker 中设置一周的第一天
Set the first day of the week in JavaFX's DatePicker
是否可以在应用阿拉伯语语言环境时更改 JavaFX 的 DatePicker 上的星期几?我需要把它从周六改到周日。
我能够通过在我的应用程序中注入以下 class 来更改一周的第一个日期:
package sun.util.resources.ar;
import sun.util.resources.LocaleNamesBundle;
public final class CalendarData_ar_SA extends LocaleNamesBundle
{
protected final Object[][] getContents()
{
return new Object[][] { { "firstDayOfWeek", "1" }, { "minimalDaysInFirstWeek", "1" } };
}
}
不要忘记更改默认语言环境:
public static final Locale SAUDI_AR_LOCALE = new Locale.Builder().setLanguageTag("ar-SA-u-nu-arab").build(); // nu is for numbers
// ....
Locale.setDefault(SAUDI_AR_LOCALE);
编辑:
之前的解决方案不适用于 Java 8 (u152) 的最新更新。实现这一目标的正确方法是使用名为 "Locale Sensitive Service Provider".
的东西
首先,创建 CalendarDataProvider 的自定义实现:
package io.fouad.utils;
import java.time.DayOfWeek;
import java.util.Locale;
import java.util.spi.CalendarDataProvider;
public class ArabicCalendarDataProvider extends CalendarDataProvider
{
private static final DayOfWeek FIRST_DAY_OF_WEEK = DayOfWeek.SUNDAY;
@Override
public int getFirstDayOfWeek(Locale locale)
{
return (FIRST_DAY_OF_WEEK.getValue() + 1) % 7;
}
@Override
public int getMinimalDaysInFirstWeek(Locale locale)
{
return 1;
}
@Override
public Locale[] getAvailableLocales()
{
return new Locale[]{new Locale("ar", "SA")};
}
@Override
public boolean isSupportedLocale(Locale locale)
{
return locale != null && "ar".equals(locale.getLanguage()) && "SA".equals(locale.getCountry());
}
}
然后创建jar文件打包ArabicCalendarDataProvider
作为服务提供者。即 jar 文件将包含以下文件:
META-INF/services/java.util.spi.CalendarDataProvider
io/fouad/utils/ArabicCalendarDataProvider.class
文件 java.util.spi.CalendarDataProvider
包含以下行:
io.fouad.utils.ArabicCalendarDataProvider
现在,为了使其正常工作,您需要将此 jar 安装为扩展,方法是将 jar 放入默认扩展目录或在启动时传递以下 JVM 参数:
-Djava.ext.dirs=path/to/the/folder/that/contains/the/jar
请注意,在 Java 9 中,如果 jar 在应用程序的 class 路径上,则区域设置敏感服务实现将直接工作。
最后,您需要修改应用程序中使用的区域设置提供程序的顺序。即传递以下 JVM 参数:
-Djava.locale.providers=SPI,CLDR,JRE,HOST
SPI
应该是第一个。
您可以按如下方式进行测试:
DayOfWeek firstDayOfWeek = WeekFields.of(new Locale("ar", "SA")).getFirstDayOfWeek();
System.out.println("firstDayOfWeek = " + firstDayOfWeek);
在默认行为中,输出为:
firstDayOfWeek = SATURDAY
当应用自定义区域设置提供程序并将 SPI
作为第一个时,输出将是:
firstDayOfWeek = SUNDAY
参见:
- LocaleServiceProvider's JavaDoc.
- Lesson: Service Providers for Internationalization.
- Why does the Java Extension Mechanism not check the classpath for an optional package implementing LocaleServiceProvider?
我找到了解决方案:
@FXML
private DatePicker date;
//In the initialize method you can use the following code:
@Override
public void initialize(URL location, ResourceBundle resources) {
//So here you need to use a Locale which actually has Monday set up as the first
//day, here the UK format has the Monday as first day, but you can try different
//options for the language that you're using
date.setOnShowing(e -> Locale.setDefault(Locale.Category.FORMAT, Locale.UK));
//...
}
是否可以在应用阿拉伯语语言环境时更改 JavaFX 的 DatePicker 上的星期几?我需要把它从周六改到周日。
我能够通过在我的应用程序中注入以下 class 来更改一周的第一个日期:
package sun.util.resources.ar;
import sun.util.resources.LocaleNamesBundle;
public final class CalendarData_ar_SA extends LocaleNamesBundle
{
protected final Object[][] getContents()
{
return new Object[][] { { "firstDayOfWeek", "1" }, { "minimalDaysInFirstWeek", "1" } };
}
}
不要忘记更改默认语言环境:
public static final Locale SAUDI_AR_LOCALE = new Locale.Builder().setLanguageTag("ar-SA-u-nu-arab").build(); // nu is for numbers
// ....
Locale.setDefault(SAUDI_AR_LOCALE);
编辑:
之前的解决方案不适用于 Java 8 (u152) 的最新更新。实现这一目标的正确方法是使用名为 "Locale Sensitive Service Provider".
的东西首先,创建 CalendarDataProvider 的自定义实现:
package io.fouad.utils;
import java.time.DayOfWeek;
import java.util.Locale;
import java.util.spi.CalendarDataProvider;
public class ArabicCalendarDataProvider extends CalendarDataProvider
{
private static final DayOfWeek FIRST_DAY_OF_WEEK = DayOfWeek.SUNDAY;
@Override
public int getFirstDayOfWeek(Locale locale)
{
return (FIRST_DAY_OF_WEEK.getValue() + 1) % 7;
}
@Override
public int getMinimalDaysInFirstWeek(Locale locale)
{
return 1;
}
@Override
public Locale[] getAvailableLocales()
{
return new Locale[]{new Locale("ar", "SA")};
}
@Override
public boolean isSupportedLocale(Locale locale)
{
return locale != null && "ar".equals(locale.getLanguage()) && "SA".equals(locale.getCountry());
}
}
然后创建jar文件打包ArabicCalendarDataProvider
作为服务提供者。即 jar 文件将包含以下文件:
META-INF/services/java.util.spi.CalendarDataProvider io/fouad/utils/ArabicCalendarDataProvider.class
文件 java.util.spi.CalendarDataProvider
包含以下行:
io.fouad.utils.ArabicCalendarDataProvider
现在,为了使其正常工作,您需要将此 jar 安装为扩展,方法是将 jar 放入默认扩展目录或在启动时传递以下 JVM 参数:
-Djava.ext.dirs=path/to/the/folder/that/contains/the/jar
请注意,在 Java 9 中,如果 jar 在应用程序的 class 路径上,则区域设置敏感服务实现将直接工作。
最后,您需要修改应用程序中使用的区域设置提供程序的顺序。即传递以下 JVM 参数:
-Djava.locale.providers=SPI,CLDR,JRE,HOST
SPI
应该是第一个。
您可以按如下方式进行测试:
DayOfWeek firstDayOfWeek = WeekFields.of(new Locale("ar", "SA")).getFirstDayOfWeek();
System.out.println("firstDayOfWeek = " + firstDayOfWeek);
在默认行为中,输出为:
firstDayOfWeek = SATURDAY
当应用自定义区域设置提供程序并将 SPI
作为第一个时,输出将是:
firstDayOfWeek = SUNDAY
参见:
- LocaleServiceProvider's JavaDoc.
- Lesson: Service Providers for Internationalization.
- Why does the Java Extension Mechanism not check the classpath for an optional package implementing LocaleServiceProvider?
我找到了解决方案:
@FXML
private DatePicker date;
//In the initialize method you can use the following code:
@Override
public void initialize(URL location, ResourceBundle resources) {
//So here you need to use a Locale which actually has Monday set up as the first
//day, here the UK format has the Monday as first day, but you can try different
//options for the language that you're using
date.setOnShowing(e -> Locale.setDefault(Locale.Category.FORMAT, Locale.UK));
//...
}