Почему средства выбора даты запускают действие JComboBox, выполненное неожиданно? - PullRequest
1 голос
/ 12 января 2012

У меня есть два компонента выбора даты и компонент JComboBox со связанными прослушивателями действий.Моя проблема заключается в следующем: когда я выбираю дату из любого средства выбора даты, запускаются не связанные с ними события, а также событие для JComboBox.Чтобы добавить к удивлению, событие для JComboBox запускается первым!

С другой стороны, когда я нажимаю на компонент JComboBox и выбираю значение, запускается только событие JComboBox, а события средства выбора даты не запускаются, что вполне нормально.Но в чем причина ситуации, описанной в предыдущем абзаце?

JComboBox event fired even if only date pickers are clicked

Чтобы пояснить это далее, приведен пример вывода с консоли.Сначала я нажимаю на первое средство выбора даты и выбираю дату:

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

Ответы [ 2 ]

2 голосов
/ 12 января 2012

Вы должны удалить fixedRangesComboBox.setSelectedIndex(-1); из двух ActionListener анонимных классов:)

1 голос
/ 12 января 2012

Есть (самый лучший обходной путь) JCalendar и SwingX , я никогда не видел проблем с Focus, Action, реализованными методами или непредвиденными событиями, используя эти два DatePickers

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...