<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Just Java IT

    西門町學士關于Java的隨便一說而已……

    JTextField內容有效性驗證幾種方式

    在使用 SwingJTextField時,我們常常希望只接受那些符合我們要求的錄入,如數字、電話號碼、郵政編碼、E-mail等。JFC工作組在這方面也做了很多工作,每一次新的Java Se發布,往往都提供了新的、更方便和強大的有效性驗證方式,在這里列舉幾種不同的驗證方式。

    • 利用鍵盤和焦點事件

    這是最直覺的方式。利用 KeyListener來選擇允許的字符,且添加FocusListener,使得

    內容不符合要求時不允許焦點轉移。這種方式很繁瑣, Sun的建議是不推薦使用這種方式。

    • 使用自定義的 Document

    我們知道, Swing組件是基于MVC實現的。JTextComponentModel是一個叫做DocumentInterface,我們可以通過限制Document的內容來達到有效性驗證的目的。javax.swing.text包中有多個不同的Document的實現,JTextField使用的是PlainDocument。如果我們希望JTextField只接受數字,可以實現我們特定的Document并使之替換默認的Document


       package sdn;

    import javax.swing.text.*;

    public class IntegerDocument extends PlainDocument {

    int currentValue = 0;

    public int getValue() {
    return currentValue;
    }

    public void insertString(int offset, String string,
    AttributeSet attributes) throws BadLocationException {

    if (string == null) {
    return;
    } else {
    String newValue;
    int length = getLength();
    if (length == 0) {
    newValue = string;
    } else {
    String currentContent = getText(0, length);
    StringBuffer currentBuffer =
    new StringBuffer(currentContent);
    currentBuffer.insert(offset, string);
    newValue = currentBuffer.toString();
    }
    currentValue = checkInput(newValue, offset);
    super.insertString(offset, string, attributes);
    }
    }
    public void remove(int offset, int length)
    throws BadLocationException {
    int currentLength = getLength();
    String currentContent = getText(0, currentLength);
    String before = currentContent.substring(0, offset);
    String after = currentContent.substring(length+offset,
    currentLength);
    String newValue = before + after;
    currentValue = checkInput(newValue, offset);
    super.remove(offset, length);
    }
    public int checkInput(String proposedValue, int offset)
    throws BadLocationException {
    if (proposedValue.length() > 0) {
    try {
    int newValue = Integer.parseInt(proposedValue);
    return newValue;
    } catch (NumberFormatException e) {
    throw new BadLocationException(proposedValue, offset);
    }
    } else {
    return 0;
    }
    }
    }

    然后用 IntegerDocument去替換JTextField默認的Document

       package sdn;

    import javax.swing.*;
    import javax.swing.text.*;
    import java.awt.*;
    import java.awt.event.*;

    public class NumericInput {
    public static void main(String args[]) {
    Runnable runner = new Runnable() {
    public void run() {
    JFrame frame = new JFrame("Numeric Input");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLayout(new GridLayout(2, 2));

    frame.add(new JLabel("Number"));
    JTextField fieldOne = new JTextField();
    Document doc= new IntegerDocument();
    fieldOne.setDocument(doc);
    frame.add(fieldOne);

    frame.add(new JLabel("All"));
    JTextField fieldTwo = new JTextField();
    frame.add(fieldTwo);

    frame.setSize(250, 90);
    frame.setVisible(true);
    }
    };
    EventQueue.invokeLater(runner);
    }
    }

    代碼很簡單,一目了然。這里說點題外話, Sun建議的Swing Applicationmain函數寫法如上所示:先建一個Runnable,然后把這個Runnable放到event-dispatch thread中去執行。另外,以前有的Developer(比如我)喜歡用SwingUtilities.invokeLater(runner)來將一個thread放到event-dispatch thread中,現在Sun也建議用EventQueue.invokeLater(runner),因為SwingUtilities方法版本僅僅是對EventQueue方法版本的一個包裝。

    • InputVerifier來實現

    J2SE 1.3中加入了一個名為InputVerifier的抽象類,可用于任何JComponent。其中定義了boolean verifiy(JComponent input)方法。如果組件中的文本是有效的,當焦點轉移時(如按下TabShift-Tab),verify方法返回true;否則返回false,使得焦點仍停留在當前組件上。我們仍以數字為例:

       package sdn;

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class NumericVerifier{
    public static void main(String args[]) {
    Runnable runner = new Runnable() {
    public void run() {
    JFrame frame = new JFrame("Numeric Verifier");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel panel1 = new JPanel(new BorderLayout());
    JLabel label1 = new JLabel("Numeric-only");
    JTextField textField1 = new JTextField();
    panel1.add(label1, BorderLayout.WEST);
    panel1.add(textField1, BorderLayout.CENTER);

    JPanel panel2 = new JPanel(new BorderLayout());
    JLabel label2 = new JLabel("Anything");
    JTextField textField2 = new JTextField();
    panel2.add(label2, BorderLayout.WEST);
    panel2.add(textField2, BorderLayout.CENTER);

    JPanel panel3 = new JPanel(new BorderLayout());
    JLabel label3 = new JLabel("Numeric-only");
    JTextField textField3 = new JTextField();
    panel3.add(label3, BorderLayout.WEST);
    panel3.add(textField3, BorderLayout.CENTER);

    InputVerifier verifier = new InputVerifier() {
    public boolean verify(JComponent comp) {
    boolean returnValue;
    JTextField textField = (JTextField)comp;
    try {
    Integer.parseInt(textField.getText());
    returnValue = true;
    } catch (NumberFormatException e) {
    Toolkit.getDefaultToolkit().beep();
    returnValue = false;
    }
    return returnValue;
    }
    };

    textField1.setInputVerifier(verifier);
    textField3.setInputVerifier(verifier);

    frame.add(panel1, BorderLayout.NORTH);
    frame.add(panel2, BorderLayout.CENTER);
    frame.add(panel3, BorderLayout.SOUTH);
    frame.setSize(300, 95);
    frame.setVisible(true);
    }
    };
    EventQueue.invokeLater(runner);
    }
    }

    這個例子的效果和上一個是不同的。自定義 DocumentApp中,用戶將會發現任何非數字的字符都不會在JTextField中出現;而在使用InputVerifierApp中,用戶在錄入字符時不會發現任何異常,但是當他確認錄入完成后,如果內容不符合有效性,焦點將不會轉移!這兩種情況都可能讓一個沒有經驗的用戶茫然,具體使用哪一種是一個見仁見智的問題。

    • 使用 Document Filter

    J2SE 1.4中,又加入了一個新的類:DocumentFilter。你無需再實現一個新的Document,而是對現有的Document過濾一遍。它的結果與實現自定義的Document并無二樣,僅僅是思路不同而已。

       package snd;
    import javax.swing.text.*;
    import java.awt.Toolkit;

    public class IntegerDocumentFilter extends DocumentFilter {


    int currentValue = 0;

    public IntegerDocumentFilter() {
    }

    public void insertString(DocumentFilter.FilterBypass fb,
    int offset, String string, AttributeSet attr)
    throws BadLocationException {

    if (string == null) {
    return;
    } else {
    replace(fb, offset, 0, string, attr);
    }
    }

    public void remove(DocumentFilter.FilterBypass fb,
    int offset, int length)
    throws BadLocationException {

    replace(fb, offset, length, "", null);
    }

    public void replace(DocumentFilter.FilterBypass fb,
    int offset, int length, String text, AttributeSet attrs)
    throws BadLocationException {

    Document doc = fb.getDocument();
    int currentLength = doc.getLength();
    String currentContent = doc.getText(0, currentLength);
    String before = currentContent.substring(0, offset);
    String after = currentContent.substring(
    length+offset, currentLength);
    String newValue = before +
    (text == null ? "" : text) + after;
    currentValue = checkInput(newValue, offset);
    fb.replace(offset, length, text, attrs);
    }

    private int checkInput(String proposedValue, int offset)
    throws BadLocationException {
    int newValue = 0;
    if (proposedValue.length() > 0) {
    try {
    newValue = Integer.parseInt(proposedValue);
    } catch (NumberFormatException e) {
    throw new BadLocationException(
    proposedValue, offset);
    }
    }
    return newValue;
    }
    }

    再將這個 Filter應用于Document

       package sdn;
    import javax.swing.*;
    import javax.swing.text.*;
    import java.awt.*;

    public class NumericInputFilter {
    public static void main(String args[]) {
    Runnable runner = new Runnable() {
    public void run() {
    JFrame frame = new JFrame("Numeric Input Filter");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLayout(new GridLayout(2, 2));

    frame.add(new JLabel("Number"));
    JTextField textFieldOne = new JTextField();
    Document doc= textFieldOne.getDocument();
    DocumentFilter filterOne = new IntegerDocumentFilter();
    ((AbstractDocument)doc).setDocumentFilter(filterOne);
    textFieldOne.setDocument(doc);
    frame.add(textFieldOne);

    frame.add(new JLabel("All"));
    JTextField textFieldTwo = new JTextField();
    frame.add(textFieldTwo);

    frame.setSize(250, 90);
    frame.setVisible(true);
    }
    };
    EventQueue.invokeLater(runner);
    }
    }

    DocumentFilter只能用于Swing中的與text有關的組件(而InputVerifier可用于任何組件)。除了這幾種方法,在對于TextField而言,我們還有JFormattedTextField,很多時候用JFormattedTextField將是非常容易和簡單的方式。

    注:這篇文章基本根據SDN的Core Java Tech Tips意譯而來,代碼基本跟其一致,另外還參考了M. Robinson & P. Vorobiev的Swing, Chapter 11

    posted on 2006-04-09 16:26 西門町學士 閱讀(2363) 評論(0)  編輯  收藏 所屬分類: Java

    主站蜘蛛池模板: 亚洲风情亚Aⅴ在线发布| 亚洲精品一区二区三区四区乱码| 亚洲欧美国产国产综合一区| 无码区日韩特区永久免费系列 | 亚洲αv在线精品糸列| 久久国产免费直播| 国产亚洲成归v人片在线观看| 一级毛片成人免费看a| 在线亚洲97se亚洲综合在线 | 久久er国产精品免费观看2| 亚洲人成网77777色在线播放| 国产亚洲免费的视频看| 亚洲天堂一区二区| 精品香蕉在线观看免费| 亚洲综合无码无在线观看| 午夜老司机免费视频| 无码AV动漫精品一区二区免费| 亚洲欭美日韩颜射在线二| 日本免费高清视频| 亚洲人成片在线观看| 国产91在线免费| 久久er国产精品免费观看8| 亚洲国产精品久久久久久| 成年人视频免费在线观看| 国产在亚洲线视频观看| 亚洲欧洲无码AV电影在线观看| 30岁的女人韩剧免费观看| 亚洲精品中文字幕| 超清首页国产亚洲丝袜| 亚洲精品视频在线免费| 亚洲jizzjizz少妇| 亚洲AV永久无码区成人网站| 午夜宅男在线永久免费观看网| 国产综合成人亚洲区| 亚洲毛片αv无线播放一区| 57PAO成人国产永久免费视频| 国产91成人精品亚洲精品| 精品久久久久久亚洲| 成年女人色毛片免费看| 两性色午夜视频免费播放| 亚洲人成图片网站|