Định dạng Text với JFormattedTextField trong Java Swing

JFormattedTextField trong Java Swing cho phép chúng ta tạo ra các định dạng văn bản mà người dùng khi nhập dữ liệu dạng văn bản phải tuân theo, ví dụ như định dạng số điện thoại, email, ngày tháng, etc. Trong thực tế JFormattedTextField thừa kế từ JTextField nên nó có hầu hết các tính năng của JTextField, nếu bạn chưa tìm hiểu JTextField thì hãy xem sơ qua đã nha.

Trong bài viết này chúng ta sẽ cùng nhau tìm hiểu một vài cách sử dụng cơ bản và thường xuyên nhất của JFormattedTextField.

Tạo JFormattedTextField với định dạng phone-number

Giả sử số điện thoại có định dạng như sau: <Mã quốc gia>-<Mã vùng>-<Số điện thoại>.

import javax.swing.*;
import javax.swing.text.MaskFormatter;
import java.awt.*;
import java.text.ParseException;

import static javax.swing.JFrame.EXIT_ON_CLOSE;

class JFormattedTextFieldTest {

    public static void main(String args[]) throws ParseException {
        JFrame jFrame = new JFrame("JFormattedTextField Example");
        jFrame.setLayout(new FlowLayout());
        // A phone number formatter - (country code)-(area code)-(number)
        MaskFormatter mf = new MaskFormatter("##-###-#######");
        mf.setPlaceholderCharacter('#');
        JFormattedTextField jftf = new JFormattedTextField(mf);
        jftf.setColumns(12);

        jFrame.add(jftf);
        jFrame.setSize(375, 250);
        jFrame.setLocationRelativeTo(null);
        jFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        jFrame.setVisible(true);
    }
}

Output

Các ký tự “#” được liệt kê trong ví dụ trên đại diện cho dữ liệu đầu vào phải là một số bất kỳ, những ký tự khác sẽ bị bỏ qua.

MaskFormatter mf = new MaskFormatter("##-###-#######");

Chúng ta có một bảng danh sách các quy ước sau có thể sử dụng trong MaskFormatter:

Character  Description
# Bất kỳ chữ số nào (Character.isDigit).
Ký tự thoát, được sử dụng để thoát bất kỳ ký tự định dạng đặc biệt nào.
U Tất cả các ký tự in hoa sẽ được chuyển thành ký tự thường
L Tất cả các ký tự thường sẽ được chuyển thành ký tự in hoa
A Bất kỳ ký tự hoặc chữ số nào đều được (Character.isLetter or Character.isDigit).
? Bất kỳ ký tự nào (Character.isLetter).
* Bất cứ thứ gì.
H Ký tự mã Hex (0-9, a-f or A-F).

Xử lý sự kiện text thay đổi

Nếu bạn muốn lắng nghe và xử lý mỗi khi văn bảng trên JFormattedTextField thay đổi thì có thể sử dụng addCaretListener() method để thêm trình xử lý như sau:

import java.text.NumberFormat;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Main {

    public static void main(String... args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel contentPane = new JPanel();

        JFormattedTextField ftf = new JFormattedTextField(
                NumberFormat.getNumberInstance());
        ftf.setColumns(10);
        ftf.setFocusLostBehavior(JFormattedTextField.PERSIST);
        ftf.setValue(100);
        ftf.addCaretListener(e -> {
            System.out.println("Text:" + ftf.getText());
        });
        contentPane.add(ftf);
        frame.setContentPane(contentPane);
        frame.setLocationRelativeTo(null);
        frame.pack();
        frame.setVisible(true);
    }
}

Khởi tạp JFormattedTextField từ DefaultFormatterFactory

import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.NumberFormat;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.NumberFormatter;

public class Main extends JPanel implements PropertyChangeListener {
    double amount = 100000;
    JFormattedTextField amountField;

    NumberFormat amountDisplayFormat;
    NumberFormat amountEditFormat;

    public Main() {
        super(new BorderLayout());
        amountDisplayFormat = NumberFormat.getCurrencyInstance();
        System.out.println(amountDisplayFormat.format(1200));
        amountDisplayFormat.setMinimumFractionDigits(0);
        amountEditFormat = NumberFormat.getNumberInstance();
        amountField = new JFormattedTextField(new DefaultFormatterFactory(
                new NumberFormatter(amountDisplayFormat), new NumberFormatter(
                amountDisplayFormat), new NumberFormatter(amountEditFormat)));
        amountField.setValue(new Double(amount));
        amountField.setColumns(10);
        amountField.addPropertyChangeListener("value", this);

        JPanel fieldPane = new JPanel(new GridLayout(0, 1));
        fieldPane.add(amountField);

        add(fieldPane, BorderLayout.LINE_END);
        add(new JButton("Hello"), BorderLayout.SOUTH);
    }

    public void propertyChange(PropertyChangeEvent e) {
        Object source = e.getSource();
        if (source == amountField) {
            amount = ((Number) amountField.getValue()).doubleValue();
            System.out.println("amount = " + amount);
            amountField.setValue(amount);
        }
    }
    public static void main(String[] args) {
        JFrame frame = new JFrame("FormatDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new Main());
        frame.pack();
        frame.setVisible(true);
    }
}

Tạo JTextField định dạng ngày tháng năm

Chúng ta có thể tạo ra một Formattedtextfield với định dạng ngày tháng nhờ sự hỗ trợ từ SimpleDateFormat và MaskFormatter 

import java.awt.BorderLayout;
import java.text.SimpleDateFormat;
import java.util.Date;
/*from   w  w w.jav  a2s .  co  m*/
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.text.MaskFormatter;

public class Main extends JPanel {

    private JFormattedTextField formatText;

    public Main() {
        Date date = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String dateString = formatter.format(date);
        formatText = new JFormattedTextField(createFormatter("####-##-## ##:##:##"));
        formatText.setColumns(20);
        formatText.setText(dateString);

        setLayout(new BorderLayout());
        add(new JLabel("Enter Date and Time in YYYY-MM-DD HH:MM:SS format"),
                BorderLayout.NORTH);
        add(formatText, BorderLayout.CENTER);
    }
    private MaskFormatter createFormatter(String s) {
        MaskFormatter formatter = null;
        try {
            formatter = new MaskFormatter(s);
        } catch (java.text.ParseException exc) {
            System.err.println("formatter is bad: " + exc.getMessage());
        }
        return formatter;
    }
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new Main());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

Nguồn tham khảo

http://www.java2s.com/Tutorials/Java/Swing_How_to/JFormattedTextField/index.htm

https://www.tutorialspoint.com/what-are-the-differences-between-a-jtextfield-and-a-jformattedtextfield-in-java

https://docs.oracle.com/javase/tutorial/uiswing/components/formattedtextfield.html

Leave a Comment

Your email address will not be published. Required fields are marked *