如何跟踪JTextField中的任何更改以立即更新其他文本字段?

时间:2015-08-18 22:01:36

标签: java swing actionlistener jtextfield

我想写一个简单的Swing应用程序。它应该根据用户输入(初始日期和天数)计算日期。 这就是我的应用程序现在的样子。 enter image description here

然而由于经验不长,我遇到了一些应用程序问题。

  1. 当中间字段textField中的值发生更改时,resultDayField中没有任何更改,但仅在按下"输入"之后。我在这里看到了如何使用DocumentListenerJFormattedField跟踪更改的不同解决方案,但我的情况需要面板中所有窗口小部件的通用侦听器同时跟踪更改。我不知道如何混合使用ActionListenerDocumentListener来处理它们。我该怎么办?

  2. 此外,如果中间字段textField为空,则选择任何日期都会使具有空指针异常的应用程序崩溃。但是我不明白为什么应用程序只能写#Null"

  3. 一段奇怪的代码

    SomeActionListener listen = new SomeActionListener(datePicker, textField, resultDateField);
    datePicker.addActionListener(listen);
    textField.addActionListener(listen);
    

    我不确定这样做是否好。

  4. 您能否对这些问题发表评论?

    以下是该应用的两个源文件。 第一个(主要)是TestJDatePicker.java

    import org.jdatepicker.JDatePicker;
    import org.jdatepicker.impl.JDatePanelImpl;
    import org.jdatepicker.impl.JDatePickerImpl;
    import org.jdatepicker.impl.UtilDateModel;
    
    import javax.swing.*;
    import java.awt.*;
    import java.util.Properties;
    
    public class TestJDatePicker extends JPanel {
        JTextField textField;
        JTextField resultDateField;
        JDatePicker datePicker;
    
        public TestJDatePicker() {
    
            Properties p = new Properties();
            p.put("text.today", "Today");
            p.put("text.month", "Month");
            p.put("text.year", "Year");
    
            UtilDateModel model = new UtilDateModel();
            JDatePanelImpl datePanel = new JDatePanelImpl(model, p);
            JDatePickerImpl datePicker = new JDatePickerImpl(datePanel, new DateLabelFormatter());
    
            textField = new JTextField(20);
            textField.setText("10");
    
            resultDateField = new JTextField(20);
    
            SomeActionListener listen = new SomeActionListener(datePicker, textField, resultDateField);
    
            datePicker.addActionListener(listen);
            textField.addActionListener(listen);
    
            add(datePicker);
            add(textField);
            add(resultDateField);
    
            setPreferredSize(new Dimension(850, 450));
            setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
        }
    
        private static void createAndShowGUI() {
            //Create and set up the window.
            JFrame frame = new JFrame("DocumentEventDemo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            //Create and set up the content pane.
            JComponent newContentPane = new TestJDatePicker();
            newContentPane.setOpaque(true); //content panes must be opaque
            frame.setContentPane(newContentPane);
    
            //Display the window.
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGUI();
                }
            });
        }
    }
    

    我写的第二个文件是SomeActionListener.java

    import org.jdatepicker.impl.JDatePickerImpl;
    
    import javax.swing.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    
    public class SomeActionListener implements ActionListener {
    
        private JTextField resultDateField;
        private JTextField textField;
        private JDatePickerImpl datePicker;
        //...
    
        public SomeActionListener(JDatePickerImpl datePicker, JTextField textField, JTextField resultDateField){
            this.textField=textField;
            this.datePicker=datePicker;
            this.resultDateField = resultDateField;
            //...
        }
    
        public void actionPerformed(ActionEvent e) {
            final SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
            Date selectedDate = (Date) datePicker.getModel().getValue();
            //System.out.println(selectedDate);
            System.out.println(textField.getText());
    
            int days = Integer.parseInt(textField.getText());
    
            Calendar cal = Calendar.getInstance();
            cal.setTime(selectedDate);
            cal.add(Calendar.DATE, days);
    
            resultDateField.setText(cal != null ? sdf.format(cal.getTime()) : null);
        }
    
    }
    

1 个答案:

答案 0 :(得分:1)

  

当中间字段textField中的值更改时,则没有   resultDayField中的更改,但仅在按“Enter”后才会更改。我在这里看到了   不同的解决方案如何使用DocumentListener跟踪更改   JFormattedField,但我的情况需要所有人的通用监听器   面板中的小部件可同时跟踪更改。我不明白   如何混合ActionListener和DocumentListener来处理它们。什么   我该怎么办?

首先创建一个方法,该方法从日期选择器和文本字段中获取值,生成所需结果并更新正确的字段

在日期选择器上使用ActionListener(或其他适当的侦听器),让此侦听器调用您的“更新”方法

在文本字段上使用DocumentListener,当调用任何事件通知方法时,调用“更新”方法

  

此外,如果中间字段textField为空,则选择任何日期   使用空指针异常使应用程序崩溃。但我没有   理解为什么应用程序不能只写“Null”。

当文本字段为空时,

int days = Integer.parseInt(textField.getText());将导致Exception,因为""不是有效数字,您需要在执行任何操作之前先检查字段是否具有值额外的计算。

至于你的上一个问题,不,这种方式使用单个监听器并不罕见。虽然我建议在您的情况下使用两个不同的侦听器,但他们将实际功能委托给共享方法