java - How do I modify the Month and Year Controls on JavaFX 8's DatePicker? -



java - How do I modify the Month and Year Controls on JavaFX 8's DatePicker? -

for application i'm developing, lot of older clients larger fingers , poor eyesight need selection arrows , date/year labels larger on datepicker pop-up.

in documentation of datepicker class, there methods described modifying datecells within calendar itself, nil describes or elaborates on construction of popup further. (at least, code not self-documented plainly plenty entry-level knowledge of java development grasp hints)

my implementation ends looking this

sometimes when open , close calendar, size of font , buttons in month/year controls fluctuate, have no thought how or why. assume css may tampering it, have no thought why work , not. css' true nature has escaped me.

i know [datepicker] based on combobox, have absolutely 0 thought how constructed , implemented, much less how modify specific elements in it.

is there method can call/override, or parameter can modify in-line style these properly? also, there combination of classes , elements can phone call in css style these avoid having outright modify datepicker described above?

here implementation:

@fxml private datepicker dpicker; final callback<datepicker, datecell> daycellfactory = new callback<datepicker, datecell>() { @override public datecell call(final datepicker datepicker) { homecoming new datecell() { @override public void updateitem(localdate item, boolean empty) { super.updateitem(item, empty); setminsize(100,100); setstyle("-fx-font-size:50px;-fx-font-weight:bold;"); } }; } }; dpicker.setdaycellfactory(daycellfactory);

...and here datapicker.java:

/* * copyright (c) 2013, oracle and/or affiliates. rights reserved. * oracle proprietary/confidential. utilize subject license terms. * * * * * * * * * * * * * * * * * * * * */ bundle javafx.scene.control; // editor , converter code in sync combobox 4858:e60e9a5396e6 import java.time.localdate; import java.time.datetimeexception; import java.time.chrono.chronology; import java.time.chrono.chronolocaldate; import java.time.chrono.isochronology; import java.time.format.datetimeformatter; import java.time.format.datetimeformatterbuilder; import java.time.format.decimalstyle; import java.time.format.formatstyle; import java.time.temporal.temporalaccessor; import java.util.arraylist; import java.util.collections; import java.util.list; import java.util.locale; import com.sun.javafx.scene.control.skin.comboboxlistviewskin; import javafx.beans.invalidationlistener; import javafx.beans.observable; import javafx.beans.property.booleanproperty; import javafx.beans.property.objectproperty; import javafx.beans.property.readonlyobjectproperty; import javafx.beans.property.readonlyobjectwrapper; import javafx.beans.property.simpleobjectproperty; import javafx.css.cssmetadata; import javafx.css.styleable; import javafx.css.styleablebooleanproperty; import javafx.css.styleableproperty; import javafx.util.callback; import javafx.util.stringconverter; import com.sun.javafx.css.converters.booleanconverter; import com.sun.javafx.scene.control.skin.datepickerskin; import com.sun.javafx.scene.control.skin.resources.controlresources; /** * datepicker command allows user come in date text or * select date calendar popup. calendar based on * either standard iso-8601 chronology or of other * chronology classes defined in java.time.chrono package. * * <p>the {@link #valueproperty() value} property represents * selected {@link java.time.localdate}. initial date can * set via {@link #datepicker(java.time.localdate) constructor} * or calling {@link #setvalue(java.time.localdate) setvalue()}. * default value null. * * <pre><code> * final datepicker datepicker = new datepicker(); * datepicker.setonaction(new eventhandler() { * public void handle(event t) { * localdate date = datepicker.getvalue(); * system.err.println("selected date: " + date); * } * }); * </code></pre> * * {@link #chronologyproperty() chronology} property specifies * calendar scheme used parsing, displaying, , choosing * dates. * {@link #valueproperty() value} property defined in * iso calendar system, however, applications based on * different chronology may utilize conversion methods provided in * {@link java.time.chrono.chronology} api or set * corresponding {@link java.time.chrono.chronolocaldate} value. * example: * * <pre><code> * localdate isodate = datepicker.getvalue(); * chronolocaldate chronodate = * ((isodate != null) ? datepicker.getchronology().date(isodate) : null); * system.err.println("selected date: " + chronodate); * </code></pre> * * * @since javafx 8.0 */ public class datepicker extends comboboxbase<localdate> { private localdate lastvaliddate = null; private chronology lastvalidchronology = isochronology.instance; /** * creates default datepicker instance <code>null</code> date value set. */ public datepicker() { this(null); valueproperty().addlistener(new invalidationlistener() { @override public void invalidated(observable observable) { localdate date = getvalue(); chronology chrono = getchronology(); if (validatedate(chrono, date)) { lastvaliddate = date; } else { system.err.println("restoring value " + ((lastvaliddate == null) ? "null" : getconverter().tostring(lastvaliddate))); setvalue(lastvaliddate); } } }); chronologyproperty().addlistener(new invalidationlistener() { @override public void invalidated(observable observable) { localdate date = getvalue(); chronology chrono = getchronology(); if (validatedate(chrono, date)) { lastvalidchronology = chrono; } else { system.err.println("restoring value " + lastvalidchronology); setchronology(lastvalidchronology); } } }); } private boolean validatedate(chronology chrono, localdate date) { seek { if (date != null) { chrono.date(date); } homecoming true; } grab (datetimeexception ex) { system.err.println(ex); homecoming false; } } /** * creates datepicker instance , sets * {@link #valueproperty() value} given date. * * @param localdate set selected date in datepicker. can null. */ public datepicker(localdate localdate) { setvalue(localdate); getstyleclass().add(default_style_class); seteditable(true); } /*************************************************************************** * * * properties * * * **************************************************************************/ /** * custom cell mill can provided customize individual * day cells in datepicker popup. refer {@link datecell} * , {@link cell} more info on cell factories. * example: * * <pre><code> * final callback&lt;datepicker, datecell&gt; daycellfactory = new callback&lt;datepicker, datecell&gt;() { * public datecell call(final datepicker datepicker) { * homecoming new datecell() { * &#064;override public void updateitem(localdate item, boolean empty) { * super.updateitem(item, empty); * * if (monthday.from(item).equals(monthday.of(9, 25))) { * settooltip(new tooltip("happy birthday!")); * setstyle("-fx-background-color: #ff4444;"); * } * if (item.equals(localdate.now().plusdays(1))) { * // tomorrow soon. * setdisable(true); * } * } * }; * } * }; * datepicker.setdaycellfactory(daycellfactory); * </code></pre> * * @defaultvalue null */ private objectproperty<callback<datepicker, datecell>> daycellfactory; public final void setdaycellfactory(callback<datepicker, datecell> value) { daycellfactoryproperty().set(value); } public final callback<datepicker, datecell> getdaycellfactory() { homecoming (daycellfactory != null) ? daycellfactory.get() : null; } public final objectproperty<callback<datepicker, datecell>> daycellfactoryproperty() { if (daycellfactory == null) { daycellfactory = new simpleobjectproperty<callback<datepicker, datecell>>(this, "daycellfactory"); } homecoming daycellfactory; } /** * calendar scheme used parsing, displaying, , choosing * dates in datepicker control. * * <p>the default value returned phone call * {@code chronology.oflocale(locale.getdefault(locale.category.format))}. * default {@link java.time.chrono.isochronology} unless * provided explicitly in {@link java.util.locale} utilize of * locale calendar extension. * * setting value <code>null</code> restore default * chronology. */ public final objectproperty<chronology> chronologyproperty() { homecoming chronology; } private objectproperty<chronology> chronology = new simpleobjectproperty<chronology>(this, "chronology", null); public final chronology getchronology() { chronology chrono = chronology.get(); if (chrono == null) { seek { chrono = chronology.oflocale(locale.getdefault(locale.category.format)); } grab (exception ex) { system.err.println(ex); } if (chrono == null) { chrono = isochronology.instance; } //system.err.println(chrono); } homecoming chrono; } public final void setchronology(chronology value) { chronology.setvalue(value); } /** * whether datepicker popup should display column showing * week numbers. * * <p>the default value specified in resource bundle, , * depends on country of current locale. */ public final booleanproperty showweeknumbersproperty() { if (showweeknumbers == null) { string country = locale.getdefault(locale.category.format).getcountry(); boolean localizeddefault = (!country.isempty() && controlresources.getnontranslatablestring("datepicker.showweeknumbers").contains(country)); showweeknumbers = new styleablebooleanproperty(localizeddefault) { @override public cssmetadata<datepicker,boolean> getcssmetadata() { homecoming styleableproperties.show_week_numbers; } @override public object getbean() { homecoming datepicker.this; } @override public string getname() { homecoming "showweeknumbers"; } }; } homecoming showweeknumbers; } private booleanproperty showweeknumbers; public final void setshowweeknumbers(boolean value) { showweeknumbersproperty().setvalue(value); } public final boolean isshowweeknumbers() { homecoming showweeknumbersproperty().getvalue(); } // --- string converter /** * converts input text object of type localdate , vice * versa. * * <p>if not set application, datepicker skin class * set converter based on {@link java.time.datetimeformatter} * current {@link java.util.locale} , * {@link #chronologyproperty() chronology}. formatter * used parse , display current date value. * * setting value <code>null</code> restore default * converter. * * <p>example using explicit formatter: * <pre><code> * datepicker.setconverter(new stringconverter&lt;localdate&gt;() { * string pattern = "yyyy-mm-dd"; * datetimeformatter dateformatter = datetimeformatter.ofpattern(pattern); * * { * datepicker.setprompttext(pattern.tolowercase()); * } * * &#064;override public string tostring(localdate date) { * if (date != null) { * homecoming dateformatter.format(date); * } else { * homecoming ""; * } * } * * &#064;override public localdate fromstring(string string) { * if (string != null && !string.isempty()) { * homecoming localdate.parse(string, dateformatter); * } else { * homecoming null; * } * } * }); * </code></pre> * <p>example wraps default formatter , catches parse exceptions: * <pre><code> * final stringconverter&lt;localdate&gt; defaultconverter = datepicker.getconverter(); * datepicker.setconverter(new stringconverter&lt;localdate&gt;() { * &#064;override public string tostring(localdate value) { * homecoming defaultconverter.tostring(value); * } * * &#064;override public localdate fromstring(string text) { * seek { * homecoming defaultconverter.fromstring(text); * } grab (datetimeparseexception ex) { * system.err.println("hellodatepicker: "+ex.getmessage()); * throw ex; * } * } * }); * </code></pre> * * @see javafx.scene.control.combobox#converterproperty */ public final objectproperty<stringconverter<localdate>> converterproperty() { homecoming converter; } private objectproperty<stringconverter<localdate>> converter = new simpleobjectproperty<stringconverter<localdate>>(this, "converter", null); public final void setconverter(stringconverter<localdate> value) { converterproperty().set(value); } public final stringconverter<localdate> getconverter() { stringconverter<localdate> converter = converterproperty().get(); if (converter != null) { homecoming converter; } else { homecoming defaultconverter; } } private stringconverter<localdate> defaultconverter = new stringconverter<localdate>() { @override public string tostring(localdate value) { if (value != null) { locale locale = locale.getdefault(locale.category.format); chronology chrono = getchronology(); chronolocaldate cdate; seek { cdate = chrono.date(value); } grab (datetimeexception ex) { system.err.println(ex); chrono = isochronology.instance; cdate = value; } datetimeformatter dateformatter = datetimeformatter.oflocalizeddate(formatstyle.short) .withlocale(locale) .withchronology(chrono) .withdecimalstyle(decimalstyle.of(locale)); string pattern = datetimeformatterbuilder.getlocalizeddatetimepattern(formatstyle.short, null, chrono, locale); if (pattern.contains("yy") && !pattern.contains("yyy")) { // modify pattern show four-digit year, including leading zeros. string newpattern = pattern.replace("yy", "yyyy"); //system.err.println("fixing pattern ("+forparsing+"): "+pattern+" -> "+newpattern); dateformatter = datetimeformatter.ofpattern(newpattern) .withdecimalstyle(decimalstyle.of(locale)); } homecoming dateformatter.format(cdate); } else { homecoming ""; } } @override public localdate fromstring(string text) { if (text != null && !text.isempty()) { locale locale = locale.getdefault(locale.category.format); chronology chrono = getchronology(); string pattern = datetimeformatterbuilder.getlocalizeddatetimepattern(formatstyle.short, null, chrono, locale); datetimeformatter df = new datetimeformatterbuilder().parselenient() .appendpattern(pattern) .toformatter() .withchronology(chrono) .withdecimalstyle(decimalstyle.of(locale)); temporalaccessor temporal = df.parse(text); chronolocaldate cdate = chrono.date(temporal); homecoming localdate.from(cdate); } homecoming null; } }; // --- editor /** * editor datepicker. * * @see javafx.scene.control.combobox#editorproperty */ private readonlyobjectwrapper<textfield> editor; public final textfield geteditor() { homecoming editorproperty().get(); } public final readonlyobjectproperty<textfield> editorproperty() { if (editor == null) { editor = new readonlyobjectwrapper<textfield>(this, "editor"); editor.set(new comboboxlistviewskin.fakefocustextfield()); } homecoming editor.getreadonlyproperty(); } /** {@inheritdoc} */ @override protected skin<?> createdefaultskin() { homecoming new datepickerskin(this); } /*************************************************************************** * * * stylesheet handling * * * **************************************************************************/ private static final string default_style_class = "date-picker"; /** * @treatasprivate implementation detail */ private static class styleableproperties { private static final string country = locale.getdefault(locale.category.format).getcountry(); private static final cssmetadata<datepicker, boolean> show_week_numbers = new cssmetadata<datepicker, boolean>("-fx-show-week-numbers", booleanconverter.getinstance(), (!country.isempty() && controlresources.getnontranslatablestring("datepicker.showweeknumbers").contains(country))) { @override public boolean issettable(datepicker n) { homecoming n.showweeknumbers == null || !n.showweeknumbers.isbound(); } @override public styleableproperty<boolean> getstyleableproperty(datepicker n) { homecoming (styleableproperty)n.showweeknumbersproperty(); } }; private static final list<cssmetadata<? extends styleable, ?>> styleables; static { final list<cssmetadata<? extends styleable, ?>> styleables = new arraylist<cssmetadata<? extends styleable, ?>>(control.getclasscssmetadata()); collections.addall(styleables, show_week_numbers ); styleables = collections.unmodifiablelist(styleables); } } /** * @return cssmetadata associated class, may include * cssmetadata of super classes. */ public static list<cssmetadata<? extends styleable, ?>> getclasscssmetadata() { homecoming styleableproperties.styleables; } /** * {@inheritdoc} */ @override public list<cssmetadata<? extends styleable, ?>> getcontrolcssmetadata() { homecoming getclasscssmetadata(); } }

...and in advance beingness patient , helping me out.

the best way alter appearance utilize external css. can refer source code default stylesheet see how defaults defined: interesting parts datepicker near bottom (lines 2932 onwards @ time of writing).

you can alter font size entire command doing

.date-picker { -fx-font-size: 18pt ; }

that ends looking little cluttered, adding bit of padding around day names helps. arrows automatically scale fit, increment size increased font size on month , year labels.

here's finish example:

import java.time.instant; import java.time.localdatetime; import java.time.zoneid; import java.time.zoneddatetime; import java.util.date; import javafx.application.application; import javafx.scene.scene; import javafx.scene.control.datepicker; import javafx.scene.layout.vbox; import javafx.stage.stage; public class datepickerexample extends application { @override public void start(stage primarystage) { datepicker datepicker = new datepicker(); vbox root = new vbox(datepicker); scene scene = new scene(root, 250, 150); scene.getstylesheets().add("date-picker-readable.css"); primarystage.setscene(scene); primarystage.show(); } public static void main(string[] args) { launch(args); } }

date-picker-readable.css:

.date-picker { -fx-font-size: 18pt; -fx-font-weight: bold ; } .date-picker .day-name-cell { -fx-padding: 10px ; }

java css user-interface datepicker javafx

Comments

Popular posts from this blog

c - Compilation of a code: unkown type name string -

java - Bypassing "final local variable defined in an enclosing type" -

json - Hibernate and Jackson (java.lang.IllegalStateException: Cannot call sendError() after the response has been committed) -