J3001. JavaFX Component Extensions (i)--integerfield, Decimalfield, and Currencyfield

Source: Internet
Author: User
Tags addall currency separator gettext locale

When we are dealing with interface presentation, we want the interface component to at least have handled the following when it comes to integer, floating-point, and amount-type data:

1, do not accept illegal input. For integral types, you can only enter numbers, minus signs, and do not allow to exceed the maximum value of shaping values on the current platform.

2. Use the thousands of bits to format the input data.

3. If it is a currency type, obtain information such as the currency symbol for the current region and format the data accordingly.

For interface handlers, this is the most basic requirement for developing a component library. In practice, however, JavaFX does not provide these or similar components. No similar components were found in the open source component. The developer of the famous Controlsfx component library provides an additional moneyfield, but the functionality is weak and support is not good.

Using Java to do the interface, you have to have this awareness: JDK provides interface functions, sometimes weak, or even more mentally retarded, you have to enrich themselves and improve their own library of components. Some third-party class libraries can sometimes be used, and sometimes special-base components have to be written by themselves. Perhaps Oracle believes that every Java interface developer is first and foremost a qualified interface component developer.

I wanted to write these three components for a long time, and there was no more. Yesterday, after work, I sat in front of my new computer, and after a while, I spent a few hours implementing the three components. Today before work, the test to improve a bit, the feeling can be put out, for everyone's reference.

First look at the effect:

There are three input boxes that accept only Integer, decimal (4 decimal), and currency types of data. and provide two buttons, one is to print the value, and the other is to assign a value to decimal by SetText ().

Put the code directly.

The Numbertypeenum enumeration class, which distinguishes between different types of input data so that the base class can be processed separately.

package com.lirong.foundation.ui.javafx.control;/** * <p>Title: LiRong Java Application Platform</p> * Description: AbstractNumberField及其子类支持的数据类型 <br> * Copyright: CorpRights lrjap.com<br> * Company: lrjap.com<br> * * @author yujj * @version 1.1.1 * @date 2017-12-27 */public enum NumberTypeEnum {    INTEGER,    CURRENCY,    DECIMAL;}

The Abstractnumberfield base class encapsulates most of the behavior, which is one of the most important classes.

Package Com.lirong.foundation.ui.javafx.control;import Java.math.bigdecimal;import Java.text.decimalformat;import Java.text.decimalformatsymbols;import Javafx.geometry.pos;import Javafx.scene.control.textfield;import Javafx.scene.input.keyevent;import org.apache.commons.lang3.stringutils;/** * <p>title:lirong Java Application platform</p> * Description: Integer, high-precision floating-point number, Currency value input box virtual base class, automatically check the legitimacy of the input, automatically increase the currency symbol, thousand points <br> * Copyright: Corprights lrjap.com<br> * company:lrjap.com<br> * * @author YUJJ * @version 1.1.1 * @date 2017-12-27 */publi    C abstract class Abstractnumberfield extends TextField {private Numbertypeenum numbertype;    private static final String Default_number_separtor_format = ", # # #";    Private final static DecimalFormatSymbols symbols = new DecimalFormatSymbols ();        Public Abstractnumberfield (Numbertypeenum numbertype) {super ();        This.numbertype = Numbertype;        Setalignment (Pos.center_right); Validity check at input AddeventfiLter (keyevent.key_typed, event, {if (!isvalid (GetText ())) {Event.consume ();        }        }); Formatted Textproperty (). AddListener ((Observablevalue, OldValue, NewValue), {if (!isvalid (NewValue))            {SetText (oldValue);        } setText (Formatvalue (Getformatter ()));    }); }/** * Formatted value * * @param valueformatter format * @return */private string Formatvalue (final string        Valueformatter) {if ("-". Equals (GetText ())) {return getText ();        } String currstring = null; if (Stringutils.isnotblank (GetText ())) {if (GetText (). EndsWith (".") | | getText (). EndsWith (Getcurrencysymbols ()            ) {return getText ();            } DecimalFormat Numberformatter = new DecimalFormat (valueformatter);        if (Numbertypeenum.integer = = This.numbertype) {INTEGER currvalue = Getintegervalue ();        currstring = Numberformatter.format (Currvalue);                } else {BigDecimal currvalue = Getdecimalvalue ();            currstring = Numberformatter.format (Currvalue);    }} return currstring; }/** * Numeric validity Check * * @param value formatted String * @return */Private Boolean isValid (final string value        {if (Stringutils.isblank (value) | | | value.equals ("-")) {return true;            } try {if (Numbertypeenum.integer = = This.numbertype) {getintegervalue ();            } else if (numbertypeenum.currency = = This.numbertype) {getdecimalvalue ();            } else {getcurrencyvalue ();        } return true;        } catch (NumberFormatException ex) {return false; }}/** * to integral type * * @return */protected Integer Getintegervalue () {if (Stringutils.isblan K (GetText ()) | | "-". Equals (GettexT ())) {return null;    } return Integer.valueof (GetText (). Replace (",", "")); }/** * to BigDecimal * * @return */protected BigDecimal Getdecimalvalue () {return Getdecima    LValue ('. '); }/** * converted to Currency * * @return */protected BigDecimal Getcurrencyvalue () {return Getdecimalvalue (    Getcurrencyseparator ()); } Private BigDecimal Getdecimalvalue (final char separator) {if (Stringutils.isblank (GetText ()) | | |        "-". Equals (GetText ())) {return null;        } int pos = GetText (). indexOf (separator);            if (pos >-1) {final String subStr = GetText (). SUBSTRING (pos + 1, GetText (). Length ());            if (Substr.length () > Decimalscale ()) {throw new NumberFormatException ("scale error.");    }} return new BigDecimal (GetText (). Replace (",", ""). Replace (Getcurrencysymbols (), ""));   /** * Generates a string for formatting data * * @return  */protected String Getformatter () {if (This.numbertype = = null) {throw new RuntimeException ("Typ        E error. ");}        if (Numbertypeenum.integer = = This.numbertype) {return getintegerformatter ();        } else if (numbertypeenum.currency = = This.numbertype) {return getcurrencyformatter ();        } else {return getdecimalformatter ();    }} protected String Getintegerformatter () {return default_number_separtor_format; } protected String Getcurrencyformatter () {return String.Format ("%s%s%s", Getcurrencysymbols (), Default_number_    Separtor_format, Getscaleformatter ()); } protected String Getdecimalformatter () {return String.Format ("%s%s", Default_number_separtor_format, Getscale    Formatter ());    } public abstract Integer Decimalscale ();         /** * Generates decimal placeholder information for BigDecimal and currency data, and how many significant decimal places are generated placeholders * * @return */protected String Getscaleformatter () { String CURrformatter = "";        if (decimalscale () = = 0) {return currformatter; } else {if (numbertypeenum.currency = = This.numbertype) {Currformatter + = Getcurrencyseparator            ();            } else {currformatter + = ".";            } Integer Tempscale = Decimalscale ();                while (Tempscale > 0) {currformatter + = "#";            tempscale--;        } return currformatter; }}/** * Get currency symbol * * @return */protected static String Getcurrencysymbols () {return SYMB    Ols.getcurrencysymbol (); }/** * Gets the currency separator * * @return */protected static char Getcurrencyseparator () {return symbols.    Getmonetarydecimalseparator (); }/** * Virtual method. Used for subclasses to return a value of the specified type * * @return */public abstract Object GetValue ();}

The following are three implementation classes, mainly processing the number of decimal digits, the type of the return value.

Currencyfield:

package com.lirong.foundation.ui.javafx.control;import java.math.BigDecimal;import java.text.DecimalFormat;import java.text.NumberFormat;import java.util.Locale;/** * <p>Title: LiRong Java Application Platform</p> * Description: <br> * Copyright: CorpRights lrjap.com<br> * Company: lrjap.com<br> * * @author yujj * @version 1.1.1 * @date 2017-12-27 */public class CurrencyField extends AbstractNumberField {    public CurrencyField() {        super(NumberTypeEnum.CURRENCY);    }    @Override    public Integer decimalScale() {        Locale locale = Locale.getDefault();        DecimalFormat formatter = (DecimalFormat) NumberFormat.getCurrencyInstance(locale);        return formatter.getCurrency().getDefaultFractionDigits();    }    @Override    public BigDecimal getValue() {        return getCurrencyValue();    }}

Decimalfield:

package com.lirong.foundation.ui.javafx.control;import java.math.BigDecimal;/** * <p>Title: LiRong Java Application Platform</p> * Description: <br> * Copyright: CorpRights lrjap.com<br> * Company: lrjap.com<br> * * @author yujj * @version 1.1.1 * @date 2017-12-27 */public class DecimalField extends AbstractNumberField {    private Integer scale = 2;    public DecimalField() {        super(NumberTypeEnum.DECIMAL);    }    public DecimalField(final Integer scale) {        this();        if (scale < 0) {            throw new NumberFormatException("Scale must great than equals to 0.");        }        this.scale = scale;    }    @Override    public Integer decimalScale() {        return this.scale;    }    @Override    public BigDecimal getValue() {        return getDecimalValue();    }}

Integerfield:

package com.lirong.foundation.ui.javafx.control;/** * <p>Title: LiRong Java Application Platform</p> * Description: <br> * Copyright: CorpRights lrjap.com<br> * Company: lrjap.com<br> * * @author yujj * @version 1.1.1 * @date 2017-12-27 */public class IntegerField extends AbstractNumberField {    public IntegerField() {        super(NumberTypeEnum.INTEGER);    }    @Override    public Integer decimalScale() {        return Integer.valueOf(0);    }    @Override    public Integer getValue() {        return getIntegerValue();    }}

Test class:

Package Com.lirong.test.ui.javafx.decimalfiled;import Com.lirong.foundation.ui.javafx.control.CurrencyField; Import Com.lirong.foundation.ui.javafx.control.decimalfield;import Com.lirong.foundation.ui.javafx.control.integerfield;import Java.math.bigdecimal;import Javafx.application.application;import Javafx.geometry.hpos;import Javafx.geometry.insets;import Javafx.scene.scene;import Javafx.scene.control.button;import Javafx.scene.control.label;import Javafx.scene.control.textarea;import Javafx.scene.layout.*;import javafx.stage.stage;/** * <p>title:lirong Java Application platform</p> * Description: <br> * copyright:corprights lrjap.com<br> * Company:lrjap    .com<br> * * @author YUJJ * @version 1.1.1 * @date 2017-12-27 */public class Testnumberfield extends application {    public static void Main (string[] args) {launch (args); } @Override public void start (Stage primarystage) {columnconstraints ColumnLabel = new Columnconstraints ();        Columnlabel.setprefwidth (120);        Columnlabel.sethalignment (Hpos.right);        Columnconstraints columncontroll = new Columnconstraints ();        Columncontroll.sethgrow (priority.always);        Gridpane Gridpane = new Gridpane ();        Gridpane.setpadding (New Insets (10));        Gridpane.sethgap (10);        Gridpane.setvgap (10);        Gridpane.getcolumnconstraints (). AddAll (ColumnLabel, Columncontroll);        Label Lblinteger = new Label ("Integer:");        Integerfield Integertextfield = new Integerfield ();        Integertextfield.setprompttext ("Please input a integer value");        Gridpane.add (lblinteger, 0, 0);        Gridpane.add (Integertextfield, 1, 0);        Label Lbldecimal = new Label ("Decimal:");        Decimalfield Decimalfield = new Decimalfield (4);        Decimalfield.setprompttext ("Please input a decimal value");        Gridpane.add (lbldecimal, 0, 1);        Gridpane.add (Decimalfield, 1, 1);        Label lblcurrency = new Label ("Currency:"); CurreNcyfield Currencyfield = new Currencyfield ();        Currencyfield.setprompttext ("Please input a currency value");        Gridpane.add (lblcurrency, 0, 2);        Gridpane.add (Currencyfield, 1, 2);        TextArea textconsole = new TextArea ();        Textconsole.seteditable (Boolean.false);        Gridpane.add (textconsole, 0, 6, 2, 6);        HBox ToolBar = new HBox ();        Toolbar.setpadding (New Insets (10));        Toolbar.setspacing (10);        Button Buttonprintvalue = New button ("Printvalue");        Buttonprintvalue.setminsize (75, 30);            Buttonprintvalue.setonaction (Action, {final String line_sep = System.getproperty ("Line.separator");            StringBuilder sbinfo = new StringBuilder (); Sbinfo.append (String.Format ("%s=%s", "Integerfield Value", Integertextfield.getvalue ())). Append (Line_sep). Append (            LINE_SEP); Sbinfo.append (String.Format ("%s=%s", "Decimalfield Value", Decimalfield.getvalue ())). Append (Line_sep). Append (line         _SEP);   Sbinfo.append (String.Format ("%s=%s", "Currencyfield Value", Currencyfield.getvalue ())). append (LINE_SEP);        Textconsole.settext (Sbinfo.tostring ());        });        Button Buttonsetvalue = New button ("SetValue");        Buttonsetvalue.setminsize (75, 30);        Buttonsetvalue.setonaction (Action-Decimalfield.settext (New BigDecimal ("2080280808.2223"). ToString ()));        Toolbar.getchildren (). AddAll (Buttonprintvalue, Buttonsetvalue);        Gridpane.add (ToolBar, 0, 4, 2, 2);        Borderpane container = new Borderpane ();        Container.setcenter (Gridpane);        Scene scene = new Scene (container, 600, 300);        Primarystage.settitle ("Integerfield, Decimalfield, Currencyfield test");        Primarystage.setscene (Scene);    Primarystage.show (); }}

Of course, estimating the use of a regular may have a simpler way of implementing it. I'll look into it when I have time.

J3001. JavaFX Component Extensions (i)--integerfield, Decimalfield, and Currencyfield

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.