为什么日期选择器会意外触发 JComboBox 的 actionPerformed?

发布于 2024-12-26 06:22:02 字数 5881 浏览 2 评论 0原文

我有两个日期选择器组件和一个 JComboBox 组件及其关联的操作侦听器。我的问题是这样的:当我从任何日期选择器中选择日期时,不会触发其关联的事件,但也会触发 JComboBox 的事件。更令人惊喜的是,JComboBox 的事件首先被触发!

另一方面,当我单击 JComboBox 组件并选择一个值时,仅触发 JComboBox 事件,而不会触发日期选择器事件,这很好。但造成上段所描述的情况的原因是什么呢?

即使仅单击日期选择器也会触发 JComboBox 事件

为了进一步说明这一点,以下是控制台的示例输出。首先,我单击第一个日期选择器并选择一个日期:(

index: -1  null
Combo Box is involved. Surprised?
This is only fired when datePicker1 is involved.

是的,我很惊讶!)然后我单击第二个日期选择器并选择一个日期:(

index: -1  null
Combo Box is involved. Surprised?
This is only fired when datePicker2 is involved.

是的,我再次感到惊讶!)最后我单击组合框并选择一个项目:

 index: 1  Last 6 months
 Combo Box is involved. Surprised?

不,我对上面的输出并不感到惊讶。

关于为什么会发生这种奇怪的情况有什么想法吗?

完整源码:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.Date;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;

import net.sourceforge.jdatepicker.JDateComponentFactory;
import net.sourceforge.jdatepicker.impl.JDatePickerImpl;
import net.sourceforge.jdatepicker.impl.UtilCalendarModel;
import org.jdesktop.swingx.JXDatePicker;

public class DatePickerDemo {

    private static boolean isDateRangeConsistent(UtilCalendarModel m1, UtilCalendarModel m2) {
        return m1.getValue().compareTo(m2.getValue()) <= 0 ? true : false;  
    }

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

        final JLabel label1 = new JLabel();
        label1.setText("Choose Range (Start - End): ");

        String[] fixedRanges = {"Last 3 months", "Last 6 months", "Last 12 months"};
        final JComboBox<String> fixedRangesComboBox = new JComboBox<String>(fixedRanges);
        fixedRangesComboBox.setSelectedIndex(-1);


        final JDatePickerImpl datePicker1 = (JDatePickerImpl) JDateComponentFactory.createJDatePicker();
        datePicker1.getModel().setSelected(true);

        final JDatePickerImpl datePicker2 = (JDatePickerImpl) JDateComponentFactory.createJDatePicker();
        datePicker2.getModel().setSelected(true);


        datePicker1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // Start date cannot be after end date!
                if ( ! isDateRangeConsistent((UtilCalendarModel) datePicker1.getModel(), 
                        (UtilCalendarModel) datePicker2.getModel())) { 
                    ((UtilCalendarModel) datePicker1.getModel())
                        .setValue(((UtilCalendarModel) datePicker2.getModel()).getValue());
                }

                //if the date range is changed by date picker, the fixed combo box becomes irrelevant
                fixedRangesComboBox.setSelectedIndex(-1);

                int rangeDaysStart = datePicker1.getModel().getDay();
                int rangeMonthsStart = 1 + datePicker1.getModel().getMonth();
                int rangeYearsStart = datePicker1.getModel().getYear();             
                label1.setText("Choose Range (Start - End): " + rangeDaysStart 
                                + "/" + rangeMonthsStart + "/" + rangeYearsStart);

                System.out.println("This is only fired when datePicker1 is involved.");
            }
        });


        datePicker2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // End date cannot be before start date!
                if ( ! isDateRangeConsistent((UtilCalendarModel) datePicker1.getModel(), 
                        (UtilCalendarModel) datePicker2.getModel())) {                  
                        ((UtilCalendarModel) datePicker2.getModel())
                            .setValue(((UtilCalendarModel) datePicker1.getModel()).getValue());
                }

                //if the date range is changed by date picker, the fixed combo box becomes irrelevant
                fixedRangesComboBox.setSelectedIndex(-1);

                int rangeDaysStart = datePicker2.getModel().getDay();
                int rangeMonthsStart = 1 + datePicker2.getModel().getMonth();
                int rangeYearsStart = datePicker2.getModel().getYear();             
                label1.setText("Choose Range (Start - End): " + rangeDaysStart 
                                + "/" + rangeMonthsStart + "/" + rangeYearsStart);

                System.out.println("This is only fired when datePicker2 is involved.");
            }
        });

        fixedRangesComboBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
              System.out.println("index: " + fixedRangesComboBox.getSelectedIndex() + "  "
                  + fixedRangesComboBox.getSelectedItem()); 

              System.out.println("Combo Box is involved. Surprised?");
            }
          });

        frame.getContentPane().add(label1, BorderLayout.NORTH);
        frame.getContentPane().add(datePicker1, BorderLayout.CENTER);        
        frame.getContentPane().add(datePicker2, BorderLayout.EAST); 
        frame.getContentPane().add(fixedRangesComboBox, BorderLayout.PAGE_END);

        //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();
            }
        });
    }
}

I have two date picker components and a JComboBox component with their associated Action Listeners. My problem is this: When I select a date from any of the date pickers, not their associated events are fired but also the event for JComboBox is fired. To add to the surprise, the event for JComboBox is fired first!

On the other hand, when I click on the JComboBox component and select a value, only the JComboBox event is fired and date picker events are not fired, which is just fine. But what is the reason of the situation described in the above paragraph?

JComboBox event fired even if only date pickers are clicked

To clarify it further, here's the sample output from console. First I click on the first date picker and select a date:

index: -1  null
Combo Box is involved. Surprised?
This is only fired when datePicker1 is involved.

(Yes, I'm surprised!) Then I click on the second date picker and select a date:

index: -1  null
Combo Box is involved. Surprised?
This is only fired when datePicker2 is involved.

(Yes, I'm surprised again!) And finally I click on the combo box and select an item:

 index: 1  Last 6 months
 Combo Box is involved. Surprised?

No, I'm not surprised by looking at the output above.

Any ideas about why this strange situation happens?

The complete source code:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.Date;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;

import net.sourceforge.jdatepicker.JDateComponentFactory;
import net.sourceforge.jdatepicker.impl.JDatePickerImpl;
import net.sourceforge.jdatepicker.impl.UtilCalendarModel;
import org.jdesktop.swingx.JXDatePicker;

public class DatePickerDemo {

    private static boolean isDateRangeConsistent(UtilCalendarModel m1, UtilCalendarModel m2) {
        return m1.getValue().compareTo(m2.getValue()) <= 0 ? true : false;  
    }

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

        final JLabel label1 = new JLabel();
        label1.setText("Choose Range (Start - End): ");

        String[] fixedRanges = {"Last 3 months", "Last 6 months", "Last 12 months"};
        final JComboBox<String> fixedRangesComboBox = new JComboBox<String>(fixedRanges);
        fixedRangesComboBox.setSelectedIndex(-1);


        final JDatePickerImpl datePicker1 = (JDatePickerImpl) JDateComponentFactory.createJDatePicker();
        datePicker1.getModel().setSelected(true);

        final JDatePickerImpl datePicker2 = (JDatePickerImpl) JDateComponentFactory.createJDatePicker();
        datePicker2.getModel().setSelected(true);


        datePicker1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // Start date cannot be after end date!
                if ( ! isDateRangeConsistent((UtilCalendarModel) datePicker1.getModel(), 
                        (UtilCalendarModel) datePicker2.getModel())) { 
                    ((UtilCalendarModel) datePicker1.getModel())
                        .setValue(((UtilCalendarModel) datePicker2.getModel()).getValue());
                }

                //if the date range is changed by date picker, the fixed combo box becomes irrelevant
                fixedRangesComboBox.setSelectedIndex(-1);

                int rangeDaysStart = datePicker1.getModel().getDay();
                int rangeMonthsStart = 1 + datePicker1.getModel().getMonth();
                int rangeYearsStart = datePicker1.getModel().getYear();             
                label1.setText("Choose Range (Start - End): " + rangeDaysStart 
                                + "/" + rangeMonthsStart + "/" + rangeYearsStart);

                System.out.println("This is only fired when datePicker1 is involved.");
            }
        });


        datePicker2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // End date cannot be before start date!
                if ( ! isDateRangeConsistent((UtilCalendarModel) datePicker1.getModel(), 
                        (UtilCalendarModel) datePicker2.getModel())) {                  
                        ((UtilCalendarModel) datePicker2.getModel())
                            .setValue(((UtilCalendarModel) datePicker1.getModel()).getValue());
                }

                //if the date range is changed by date picker, the fixed combo box becomes irrelevant
                fixedRangesComboBox.setSelectedIndex(-1);

                int rangeDaysStart = datePicker2.getModel().getDay();
                int rangeMonthsStart = 1 + datePicker2.getModel().getMonth();
                int rangeYearsStart = datePicker2.getModel().getYear();             
                label1.setText("Choose Range (Start - End): " + rangeDaysStart 
                                + "/" + rangeMonthsStart + "/" + rangeYearsStart);

                System.out.println("This is only fired when datePicker2 is involved.");
            }
        });

        fixedRangesComboBox.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
              System.out.println("index: " + fixedRangesComboBox.getSelectedIndex() + "  "
                  + fixedRangesComboBox.getSelectedItem()); 

              System.out.println("Combo Box is involved. Surprised?");
            }
          });

        frame.getContentPane().add(label1, BorderLayout.NORTH);
        frame.getContentPane().add(datePicker1, BorderLayout.CENTER);        
        frame.getContentPane().add(datePicker2, BorderLayout.EAST); 
        frame.getContentPane().add(fixedRangesComboBox, BorderLayout.PAGE_END);

        //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();
            }
        });
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

故人如初 2025-01-02 06:22:02

您应该从两个 ActionListener 匿名类中删除 fixedRangesComboBox.setSelectedIndex(-1); :)

You should remove fixedRangesComboBox.setSelectedIndex(-1); from the two ActionListener anonymous classes :)

柒七 2025-01-02 06:22:02

有(最好的解决方法) JCalendarSwingX,我从未见过任何 FocusAction、实现的方法或意外事件的问题,通过使用这两个日期选择器

There are (most better workaround) JCalendar and SwingX, I never saw any issues with Focus, Action, implemented methods or un_expected events, by using these two DatePickers

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文