如何实现DocumentListener

3

我创建了一些文本字段,希望使用用户输入。我读到应该使用 DocumentListener 来实现,但是我在想如何正确地实现它。

在代码中,我试图将其实现到文本字段 tf1 上。输入的 im 应该被解析为 double 类型,这样我就可以对其进行一些数学计算。

以下是我尝试实现的代码。

import java.awt.ComponentOrientation;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;


public class Display {
final static boolean shouldFill = true;
final static boolean shouldWeightX = true;
final static boolean RIGHT_TO_LEFT = false;

public static void addComponentsToPane(Container pane) {

    if (RIGHT_TO_LEFT) {
        pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
    }
    JButton button;
    JLabel label;

    pane.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();
    if (shouldFill) {
    //natural height, maximum width
    c.fill = GridBagConstraints.HORIZONTAL;
    }
    if (shouldWeightX) {
    c.weightx = 0.5;
    }

    ...

    button = new JButton("Value Bet");
    c.fill = GridBagConstraints.HORIZONTAL;
    c.ipady = 0;
    c.gridx = 0;
    c.gridy = 1;
    pane.add(button, c);
    button.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e)
        {
            //Execute when button is pressed
            JFrame frame = new JFrame("Value Bet");
            frame.setVisible(true);
            frame.setSize(500,300);
            GridBagLayout layout = new GridBagLayout();
            frame.setLayout(layout);
            GridBagConstraints c = new GridBagConstraints();

            JLabel label;
            JTextField tf;

            if (shouldFill) {
            //natural height, maximum width
            c.fill = GridBagConstraints.HORIZONTAL;
            }
            if (shouldWeightX) {
            c.weightx = 0.5;
            }

            ...

            final JTextField tf1 = new JTextField();
            c.fill = GridBagConstraints.HORIZONTAL;
            c.gridx = 1;
            c.gridy = 2;
            frame.add(tf1, c);

            tf1.getDocument().addDocumentListener(new DocHandler(){
                public class DocHandler implements DocumentListener{

                    @Override
                    public void changedUpdate(DocumentEvent arg0) {
                        tfHasChanged();

                    }

                    @Override
                    public void insertUpdate(DocumentEvent arg0) {
                        tfHasChanged();

                    }

                    @Override
                    public void removeUpdate(DocumentEvent arg0) {
                        tfHasChanged();

                    }

                }

                public void tfHasChanged(){
                    double chance1 = Double.parseDouble(tf1.getText());
                }
            });      

            ... div components


}

 private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("Betting Application");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Set up the content pane.
        addComponentsToPane(frame.getContentPane());

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

 public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

我建议您放弃这种方法,改用模态对话框,就像我在您上一个问题的答案中建议的那样。或者为了获得最好的帮助,至少解释一下为什么您不想采取那种方法。 - Andrew Thompson
为了更快地获得更好的帮助,请发布一个SSCCE - Andrew Thompson
2个回答

4

对于数字,您需要实现DocumentFilter或直接使用带有数字格式化程序的JFormattedTextField

然后可能的方法(阻止执行)代码行

formatter.setMinimum(0.0);
formatter.setMaximum(1000.00);

并且为textField1添加一些公式,例如textField1等于来自textField2的值,例如。

import java.awt.*;
import java.awt.font.TextAttribute;
import java.math.*;
import java.text.*;
import java.util.Map;
import javax.swing.*;
import javax.swing.JFormattedTextField.*;
import javax.swing.event.*;
import javax.swing.text.InternationalFormatter;

public class DocumentListenerAdapter {

    public static void main(String args[]) {
        JFrame frame = new JFrame("AbstractTextField Test");
        final JFormattedTextField textField1 = new JFormattedTextField(new Float(10.01));
        textField1.setFormatterFactory(new AbstractFormatterFactory() {

            @Override
            public AbstractFormatter getFormatter(JFormattedTextField tf) {
                NumberFormat format = DecimalFormat.getInstance();
                format.setMinimumFractionDigits(2);
                format.setMaximumFractionDigits(2);
                format.setRoundingMode(RoundingMode.HALF_UP);
                InternationalFormatter formatter = new InternationalFormatter(format);
                formatter.setAllowsInvalid(false);
                formatter.setMinimum(0.0);
                formatter.setMaximum(1000.00);
                return formatter;
            }
        });
        final Map attributes = (new Font("Serif", Font.BOLD, 16)).getAttributes();
        attributes.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
        final JFormattedTextField textField2 = new JFormattedTextField(new Float(10.01));
        textField2.setFormatterFactory(new AbstractFormatterFactory() {

            @Override
            public AbstractFormatter getFormatter(JFormattedTextField tf) {
                NumberFormat format = DecimalFormat.getInstance();
                format.setMinimumFractionDigits(2);
                format.setMaximumFractionDigits(2);
                format.setRoundingMode(RoundingMode.HALF_UP);
                InternationalFormatter formatter = new InternationalFormatter(format);
                formatter.setAllowsInvalid(false);
                //formatter.setMinimum(0.0);
                //formatter.setMaximum(1000.00);
                return formatter;
            }
        });
        textField2.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void changedUpdate(DocumentEvent documentEvent) {
                printIt(documentEvent);
            }

            @Override
            public void insertUpdate(DocumentEvent documentEvent) {
                printIt(documentEvent);
            }

            @Override
            public void removeUpdate(DocumentEvent documentEvent) {
                printIt(documentEvent);
            }

            private void printIt(DocumentEvent documentEvent) {
                DocumentEvent.EventType type = documentEvent.getType();
                double t1a1 = (((Number) textField2.getValue()).doubleValue());
                if (t1a1 > 1000) {
                    Runnable doRun = new Runnable() {

                        @Override
                        public void run() {
                            textField2.setFont(new Font(attributes));
                            textField2.setForeground(Color.red);
                        }
                    };
                    SwingUtilities.invokeLater(doRun);
                } else {
                    Runnable doRun = new Runnable() {

                        @Override
                        public void run() {
                            textField2.setFont(new Font("Serif", Font.BOLD, 16));
                            textField2.setForeground(Color.black);
                        }
                    };
                    SwingUtilities.invokeLater(doRun);
                }
            }
        });
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(textField1, BorderLayout.NORTH);
        frame.add(textField2, BorderLayout.SOUTH);
        frame.setVisible(true);
        frame.pack();
    }

    private DocumentListenerAdapter() {
    }
}

考虑到“Value Bet”,我认为最好的组件应该是带有“NumberModel”的JSpinner - 但是看起来提问者似乎忽略了我的建议。 :) - Andrew Thompson
1
@Andrew Thompson 确定 BNI,我的错。默认情况下,我从不检查提问者的用户资料,这是为了保护我的心理健康 :-) - mKorbel
我通常不检查个人资料,只有当我有一种压倒性的“似曾相识”的感觉时才会查看(哦,别激动,那些有趣的小重音可能是正确的,因为我是从维基百科复制/粘贴的Déjà vu ;))。 - Andrew Thompson

1
如果tf1是一个文本字段,那么需要实现Document Listener接口的3个方法:changedUpdate、insertUpdate和removeUpdate。
tf1.getDocument().addDocumentListener(new DocumentListener() {

    @Override
        public void changedUpdate(DocumentEvent e){

                              //do some math
                               tf1.getText(); 
                                   }

        @Override
        public void insertUpdate(DocumentEvent e) {

                                  /do some math
                               tf1.getText(); 
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            // TODO Auto-generated method stub

        }
});    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接