JFormattedTextfield仅在按下enter时验证

时间:2012-04-22 09:43:05

标签: java swing jformattedtextfield

对于任务,我需要使用以下行为创建JFormattedTextField:

  • 如果编辑了值且不等于上次验证的值,则背景必须变为黄色。
  • 可以随时进行价值验证
  • 如果焦点丢失,则不会发生任何事情(如果背景为黄色,则应保持黄色,......)
  • 按Enter键时应采取措施

我似乎无法找到正确的听众组合来实现这一目标。我尝试使用KeyAdapterInputVerifierPropertyChangeListener,但这给了我非常丑陋的代码,仅适用于80%。

应该怎么做?

编辑:我写了一个小例子:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.text.ParseException;

import javax.swing.AbstractAction;
import javax.swing.InputVerifier;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Test extends JPanel {

    private JFormattedTextField field;
    private JLabel label;
    private JButton btn;

    public Test() {
        super(new BorderLayout());

        label = new JLabel("Enter a float value:");
        btn = new JButton(new AbstractAction("Print to stdout"){

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println(field.getValue());
            }

        });
        field = new JFormattedTextField(new Float(9.81));

        field.addKeyListener(new KeyAdapter(){

            @Override
            public void keyPressed(KeyEvent e){
                field.setBackground(Color.YELLOW);
            }

            @Override 
            public void keyTyped(KeyEvent e){
                if(e.getKeyCode() == KeyEvent.VK_ENTER){
                    try{
                        field.commitEdit();
                        field.setBackground(Color.WHITE);
                    }catch(ParseException e1){
                        field.setBackground(Color.RED);
                    }
                }
            }
        });

        field.setInputVerifier(new InputVerifier(){

            @Override
            public boolean verify(JComponent comp) {
                try{
                    field.commitEdit();
                    field.setBackground(Color.YELLOW);
                    return true;
                }catch(ParseException e){
                    field.setBackground(Color.RED);
                    return false;
                }
            }

        });

        add(label, BorderLayout.NORTH);
        add(field, BorderLayout.CENTER);
        add(btn, BorderLayout.SOUTH);
    }


    public static void main(String[] args) {
        JFrame window = new JFrame("InputVerifier test program");
        Container cp = window.getContentPane();
        cp.add(new Test());
        window.pack();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setVisible(true);
    }
}

这几乎可以满足我的一切需求。但问题是ENTER键永远不会被捕获。我认为它在到达我的KeyListener之前被消耗了,但是我怎么能阻止它?

即使可以防止这种情况,我仍然觉得应该有更清洁的原因来完成上面的代码。

1 个答案:

答案 0 :(得分:4)

尝试使用此代码示例,告诉我这是您想要的行为,或者您期待的是其他内容,除此之外:

import java.awt.*;
import java.awt.event.*;
import java.text.NumberFormat;
import javax.swing.*;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;

public class JFormattedExample
{
    private String lastValidValue;

    private void createAndDisplayGUI()
    {
        JFrame frame = new JFrame("JFormattedTextField Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        contentPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        final JFormattedTextField ftf = new JFormattedTextField(
                            NumberFormat.getNumberInstance());
        ftf.setColumns(10);
        ftf.setFocusLostBehavior(JFormattedTextField.PERSIST);
        ftf.setValue(100);
        lastValidValue = "100";
        ftf.addCaretListener(new CaretListener()
        {
            public void caretUpdate(CaretEvent ce)
            {
                System.out.println("Last Valid Value : " + lastValidValue);
                if (ftf.isEditValid())
                {
                    String latestValue = ftf.getText();
                    System.out.println("Latest Value : " + latestValue);
                    if (!(latestValue.equals(lastValidValue)))
                        ftf.setBackground(Color.YELLOW.darker());
                    else
                    {
                        lastValidValue = ftf.getText();
                        ftf.setBackground(Color.WHITE);
                    }
                }
                else
                {
                    System.out.println("Invalid Edit Entered.");
                }
            }
        });

        contentPane.add(ftf);
        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new JFormattedExample().createAndDisplayGUI();
            }
        });
    }
}