<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∨无码一区二区三区| 午夜视频免费在线观看| 又黄又爽又成人免费视频| 亚洲综合无码一区二区| 国产高清不卡免费视频| 亚洲国产精品久久久天堂| 成人性生免费视频| 在线观看免费精品国产| 亚洲av中文无码乱人伦在线观看| 99久久免费国产精精品| 亚洲热线99精品视频| 亚洲人成色77777在线观看| 爱丫爱丫影院在线观看免费| 女人被男人躁的女爽免费视频| 亚洲男人的天堂久久精品| 蜜桃视频在线观看免费网址入口| 亚洲欧洲日产国码av系列天堂| 久久九九久精品国产免费直播| 亚洲AV无码不卡在线播放| 30岁的女人韩剧免费观看| 青青青国产色视频在线观看国产亚洲欧洲国产综合 | 小说专区亚洲春色校园| 亚洲麻豆精品国偷自产在线91| 免费国产va视频永久在线观看| 亚洲五月午夜免费在线视频| 国产一精品一AV一免费| 337p欧洲亚洲大胆艺术| 亚洲黄色片免费看| 中文字幕永久免费| 久久精品国产亚洲AV大全| 两性刺激生活片免费视频| 国产精品亚洲专区在线播放| 久草视频免费在线观看| 亚洲av无码有乱码在线观看| 精品亚洲视频在线观看| 1000部拍拍拍18勿入免费视频下载| 亚洲精品无码国产片| 亚洲gv猛男gv无码男同短文| 歪歪漫画在线观看官网免费阅读| 青青草国产免费国产是公开| 亚洲欧洲春色校园另类小说|