1

对于一项任务,我需要创建一个具有以下行为的 JFormattedTextField:

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

我似乎无法找到正确的侦听器组合来完成此操作。我尝试使用KeyAdapter,但这给了我非常丑陋的代码,仅适用于 80% InputVerifierPropertyChangeListener

这应该怎么做?

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

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 之前就被消耗掉了,但是我怎样才能防止这种情况呢?

即使可以避免这种情况,我仍然觉得应该更清楚为什么要完成上面的代码。

4

1 回答 1

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();
            }
        });
    }
}
于 2012-04-22T10:54:01.067 回答