2012-01-12 46 views
1

我有兩個日期選擇器組件和一個JComboBox組件及其關聯的Action Listeners。我的問題是這樣的:當我從任何日期選擇器中選擇一個日期時,不會觸發它們相關的事件,而且JComboBox的事件也會被觸發。令人驚訝的是,JComboBox事件首先被觸發!另一方面,當我點擊JComboBox組件並選擇一個值時,只有JComboBox事件被激發,並且日期選取器事件不會被觸發,這就好了。但上段所述情況的原因是什麼?爲什麼日期選擇器意外觸發JComboBox的actionPerformed?

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

_JComboBox的事件被解僱first_ no ,情況並非如此,相反,它只是由於打印輸出的順序而出現:拾取器觸發其actionEvent,在您的偵聽器中更改組合鍵,觸發組合鍵的動作,在其打印出消息的偵聽器中,然後回到選擇器的監聽器,其他消息打印 – kleopatra 2012-01-12 14:33:53

回答

2

您應該從兩個ActionListener匿名類刪除fixedRangesComboBox.setSelectedIndex(-1); :)

+0

但是,然後我怎麼能「重置」組合框?在我的用例中,如果用戶在組合框中選擇了某些內容,然後從日期選擇器中選擇了一個日期,我希望組合框被重置。 – 2012-01-12 11:44:42

+0

@EmreSevinç不明白你爲什麼感到驚訝 - 總是改變組合的選擇觸發actionEvent。這意味着當你以編程方式改變選擇時觸發...... – kleopatra 2012-01-12 14:27:42

+0

換句話說:我需要通過點擊組合選擇一個項目來區分「改變組合的選擇」,並且在日期選擇器的actionPerformed內「改變組合的選擇」功能。 – 2012-01-12 19:19:05

1

有(最好解決方法)JCalendarSwingX,我從來沒有見過任何問題FocusAction,實現的方法或un_expected事件,通過這兩個DatePickers

+1

刪除最後的評論,OP是_not_使用JXDatePicker - 被未使用的導入愚弄了;-) – kleopatra 2012-01-12 14:24:54

相關問題