2017-05-01 41 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而该领域有重点 默认情况下,当该领域失去焦点。“ –