2017-05-01 121 views
1

我有下面的示例代碼,我有理解它的問題。所以我想要兩問兩個問題:這個JFormattedTextField是如何工作的?

  1. 爲什麼JFormattedTextField上有一個「值」(getValue()setValue())和一個JTextField不?

  2. propertyChange()方法,爲什麼它足夠寫:

    amount = ((Number)amountField.getValue()).doubleValue();

    ,使其顯示正確的方式來更新量,但對於paymentField我必須調用setValue()方法?

示例: 「(的getValue()的setValue())和一個JTextField不是 」

/* 
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved. 
* 
* Redistribution and use in source and binary forms, with or without 
* modification, are permitted provided that the following conditions 
* are met: 
* 
* - Redistributions of source code must retain the above copyright 
*  notice, this list of conditions and the following disclaimer. 
* 
* - Redistributions in binary form must reproduce the above copyright 
*  notice, this list of conditions and the following disclaimer in the 
*  documentation and/or other materials provided with the distribution. 
* 
* - Neither the name of Oracle or the names of its 
*  contributors may be used to endorse or promote products derived 
*  from this software without specific prior written permission. 
* 
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
*/ 



import java.awt.*; 
import java.awt.event.*; 

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

import java.beans.PropertyChangeListener; 
import java.beans.PropertyChangeEvent; 

import java.text.*; 

/** 
* FormattedTextFieldDemo.java requires no other files. 
* 
* It implements a mortgage calculator that uses four 
* JFormattedTextFields. 
*/ 
public class FormattedTextFieldDemo extends JPanel 
            implements PropertyChangeListener { 
    //Values for the fields 
    private double amount = 100000; 
    private double rate = 7.5; //7.5% 
    private int numPeriods = 30; 

    //Labels to identify the fields 
    private JLabel amountLabel; 
    private JLabel rateLabel; 
    private JLabel numPeriodsLabel; 
    private JLabel paymentLabel; 

    //Strings for the labels 
    private static String amountString = "Loan Amount: "; 
    private static String rateString = "APR (%): "; 
    private static String numPeriodsString = "Years: "; 
    private static String paymentString = "Monthly Payment: "; 

    //Fields for data entry 
    private JFormattedTextField amountField; 
    private JFormattedTextField rateField; 
    private JFormattedTextField numPeriodsField; 
    private JFormattedTextField paymentField; 

    //Formats to format and parse numbers 
    private NumberFormat amountFormat; 
    private NumberFormat percentFormat; 
    private NumberFormat paymentFormat; 

    public FormattedTextFieldDemo() { 
     super(new BorderLayout()); 
     setUpFormats(); 
     double payment = computePayment(amount, 
             rate, 
             numPeriods); 

     //Create the labels. 
     amountLabel = new JLabel(amountString); 
     rateLabel = new JLabel(rateString); 
     numPeriodsLabel = new JLabel(numPeriodsString); 
     paymentLabel = new JLabel(paymentString); 

     //Create the text fields and set them up. 
     amountField = new JFormattedTextField(amountFormat); 
     amountField.setValue(new Double(amount)); 
     amountField.setColumns(10); 
     amountField.addPropertyChangeListener("value", this); 

     rateField = new JFormattedTextField(percentFormat); 
     rateField.setValue(new Double(rate)); 
     rateField.setColumns(10); 
     rateField.addPropertyChangeListener("value", this); 

     numPeriodsField = new JFormattedTextField(); 
     numPeriodsField.setValue(new Integer(numPeriods)); 
     numPeriodsField.setColumns(10); 
     numPeriodsField.addPropertyChangeListener("value", this); 

     paymentField = new JFormattedTextField(paymentFormat); 
     paymentField.setValue(new Double(payment)); 
     paymentField.setColumns(10); 
     paymentField.setEditable(false); 
     paymentField.setForeground(Color.red); 

     //Tell accessibility tools about label/textfield pairs. 
     amountLabel.setLabelFor(amountField); 
     rateLabel.setLabelFor(rateField); 
     numPeriodsLabel.setLabelFor(numPeriodsField); 
     paymentLabel.setLabelFor(paymentField); 

     //Lay out the labels in a panel. 
     JPanel labelPane = new JPanel(new GridLayout(0,1)); 
     labelPane.add(amountLabel); 
     labelPane.add(rateLabel); 
     labelPane.add(numPeriodsLabel); 
     labelPane.add(paymentLabel); 

     //Layout the text fields in a panel. 
     JPanel fieldPane = new JPanel(new GridLayout(0,1)); 
     fieldPane.add(amountField); 
     fieldPane.add(rateField); 
     fieldPane.add(numPeriodsField); 
     fieldPane.add(paymentField); 

     //Put the panels in this panel, labels on left, 
     //text fields on right. 
     setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); 
     add(labelPane, BorderLayout.CENTER); 
     add(fieldPane, BorderLayout.LINE_END); 
    } 

    /** Called when a field's "value" property changes. */ 
    public void propertyChange(PropertyChangeEvent e) { 
     Object source = e.getSource(); 
     if (source == amountField) { 
      amount = ((Number)amountField.getValue()).doubleValue(); 
     } else if (source == rateField) { 
      rate = ((Number)rateField.getValue()).doubleValue(); 
     } else if (source == numPeriodsField) { 
      numPeriods = ((Number)numPeriodsField.getValue()).intValue(); 
     } 

     double payment = computePayment(amount, rate, numPeriods); 
     paymentField.setValue(new Double(payment)); 
    } 

    /** 
    * Create the GUI and show it. For thread safety, 
    * this method should be invoked from the 
    * event dispatch thread. 
    */ 
    private static void createAndShowGUI() { 
     //Create and set up the window. 
     JFrame frame = new JFrame("FormattedTextFieldDemo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     //Add contents to the window. 
     frame.add(new FormattedTextFieldDemo()); 

     //Display the window. 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     //Schedule a job for the event dispatch thread: 
     //creating and showing this application's GUI. 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       //Turn off metal's use of bold fonts 
      UIManager.put("swing.boldMetal", Boolean.FALSE); 
       createAndShowGUI(); 
      } 
     }); 
    } 

    //Compute the monthly payment based on the loan amount, 
    //APR, and length of loan. 
    double computePayment(double loanAmt, double rate, int numPeriods) { 
     double I, partial1, denominator, answer; 

     numPeriods *= 12;  //get number of months 
     if (rate > 0.01) { 
      I = rate/100.0/12.0;   //get monthly rate from annual 
      partial1 = Math.pow((1 + I), (0.0 - numPeriods)); 
      denominator = (1 - partial1)/I; 
     } else { //rate ~= 0 
      denominator = numPeriods; 
     } 

     answer = (-1 * loanAmt)/denominator; 
     return answer; 
    } 

    //Create and set up number formats. These objects also 
    //parse numbers input by user. 
    private void setUpFormats() { 
     amountFormat = NumberFormat.getNumberInstance(); 

     percentFormat = NumberFormat.getNumberInstance(); 
     percentFormat.setMinimumFractionDigits(3); 

     paymentFormat = NumberFormat.getCurrencyInstance(); 
    } 
} 

回答

0

「 爲什麼有一個的JFormattedTextField的」 值

JTextFieldJFormattedTextField的文本屬性是您看到的每個文本顯示的文本屬性。但JFormattedTextField不只是顯示一些你給它的文字。它在你提供的格式化程序的幫助下,在一些對象之間進行轉換 - 在這種情況下是一個數字 - 以及在屏幕上看到的便於閱讀的文本表示。您正在顯示的值的對象是JFormattedTextField的「值」,它在屏幕上的外觀是「文本」。另一方面,一般的JTextField只顯示你告訴它顯示的任何文本,並返回你輸入的任何內容,所以不需要單獨的值屬性,因爲它總是與「文本」相同。

「爲什麼要寫」amount =((Number)amountField.getValue())。doubleValue();「來更新金額,以便以正確的方式顯示,但對於我必須調用的paymentField setValue-Methode?「

你不寫

amount = ((Number)amountField.getValue()).doubleValue(); 

更新amountField,你這樣做,找出哪些用戶輸入到amountFieldamountField正在更新自身以響應用戶輸入,因爲這就是JFormattedTextField的功能。

現在,在瞭解了用戶輸入到amountField後,您重新計算了付款金額,並通過調用setValue方法告訴paymentField顯示新付款。

+0

非常感謝! :)所以amountField被更新,因爲當用戶按下Enter時,默認情況下調用commitEdit()方法?因爲我在Oracle的網站上發現了這種情況:「commitEdit方法將值設置爲格式化程序確定的任何對象由字段的文本表示。當發生以下任一情況時,會自動調用commitEdit方法: 當用戶按Enter而該領域有重點 默認情況下,當該領域失去焦點。「 –