2015-11-22 35 views
1

我在JCalendar中設置自定義第一天的問題時遇到了問題。 如果我更改區域設置,第一天的確會發生變化。 但是,如果更改基礎日曆的第一個星期,則不起作用。如何在JCalendar中設置自定義星期開始?

這裏是一個簡短的演示代碼:

public class TestJChooser extends JFrame { 

    /** 
    * 
    */ 
    public TestJChooser() { 

     setLayout(new BorderLayout(5,5)); 
     setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); 

     Locale locale = Locale.forLanguageTag("de-DE"); 

     Calendar calendar = Calendar.getInstance(locale); 
     calendar.setFirstDayOfWeek(Calendar.TUESDAY); 

     JCalendar jCal = new JCalendar(calendar); 
     jCal.setLocale(locale); 
     jCal.setPreferredSize(new Dimension(500, 400)); 
     jCal.getDayChooser().setDayBordersVisible(true); 
     jCal.setTodayButtonVisible(true); 
     getContentPane().add(jCal,BorderLayout.CENTER); 

     pack(); 
     setVisible(true); 

    } 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 

     new TestJChooser(); 

    } 
} 

改變的

calendar.setFirstDayOfWeek(Calendar.TUESDAY); 

值不改變一週的第一天JCalendar,也不是週末的一天。

+0

同樣的問題,與2013年沒有真正的答案:http://stackoverflow.com/questions/19095185/set-first-day-of-week-in-jdatechooser – c0der

回答

1

爲了實現我使用com.toedter.calendar.JDateChooser所需的功能,我必須對其進行擴展。

首先演示:將星期日設置爲一週的第一天(儘管它由語言環境設置爲星期一)。測試等級:

public class TestJXChooser extends JFrame { 

     /** 
     * 
     */ 
     public TestJXChooser(){ 

      setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); 

      getContentPane().setLayout(new GridLayout(0, 1, 0, 0)); 
      getContentPane().setLayout(new BorderLayout(5,5)); 

      //set locale and calendar 
      Locale locale = Locale.forLanguageTag("de-DE"); 

      Calendar cal = Calendar.getInstance(locale); 
      cal.setTime(new Date()); 
      //set first day of week 
      int firstWeekDay = Calendar.SUNDAY; 
      cal.setFirstDayOfWeek(firstWeekDay); 

      //-- Toedter JCalendar 

      JCalendar jCalendar = new JCalendarExt(null, locale, true, true, false); 
      jCalendar.setCalendar(cal); 
      jCalendar.setPreferredSize(new Dimension(120, 160)); 
      jCalendar.getDayChooser().setDayBordersVisible(true); 
      jCalendar.setTodayButtonVisible(true); 
      jCalendar.setWeekOfYearVisible(false); 

      getContentPane().add(jCalendar,BorderLayout.CENTER); 

      //-- Toedter JDateChooser 
      JCalendar jCalendar2 = new JCalendarExt(null, locale, true, true, false); 
      jCalendar2.setCalendar(cal); 
      JDateChooser dateChooser = new JDateChooser(jCalendar2, null , "dd.mm.yyyy",null); 
      dateChooser.setLocale(locale); 

      getContentPane().add(dateChooser,BorderLayout.SOUTH); 

      pack(); 
      setVisible(true); 

     } 

     /** 
     * @param args 
     */ 
     public static void main(String[] args) { 

      new TestJXChooser(); 

     } 

    } 

結果可以在圖像中看到。

set Sunday as the first day of the week
第二張圖像演示了將星期幾的第一天設置爲星期二。

setting the first-day-of-week to Tuesday
分爲兩個等級。擴展JCalendar類:

/** 
    * Extended to gain control on week-first-day. 
    * It also enables the option to display in different color the 
    * last-day-of-week, rather than <code>JCalendar</code> default which is 
    * always display Sunday in a different color. 
    * 
    * @version 
    * $Log: JCalendarExt.java,v $ 
    * 
    * 
    * @author Ofer Yuval 
    * 27 Nov 2015 
    * 
    */ 
    public class JCalendarExt extends JCalendar { 

     /** 
     * 
     * @param date 
     * @param locale 
     * @param monthSpinner 
     * @param weekOfYearVisible 
     * @param colorWeekend 
     *  <br>When false, week-first-day will be painted in red, as in <code>JDayChooser</code>. 
     *  <br>When true, week-last-day will be painted in red. 
     */ 

     public JCalendarExt(Date date, Locale locale, boolean monthSpinner, boolean weekOfYearVisible, 
       boolean colorWeekend) { 

      super(date, locale, monthSpinner, weekOfYearVisible); 

      remove(dayChooser); 

      //add the extended date chooser 
      dayChooser = new JDayChooserExt(weekOfYearVisible) ; 
      dayChooser.addPropertyChangeListener(this); 
      ((JDayChooserExt) dayChooser).setColorWeekend(colorWeekend); 

      monthChooser.setDayChooser(dayChooser); 
      yearChooser.setDayChooser(dayChooser); 

      add(dayChooser, BorderLayout.CENTER); 

     } 

     @Override 
     public void setCalendar(Calendar c) { 

      getDayChooser().setCalendar(c); 
      super.setCalendar(c); 
     } 

    } 

和類擴展JDayChooser:

/** 
    * 
    * @version 
    * $Log: JDayChooserExt.java,v $ 
    * 
    * 
    * @author Ofer Yuval 
    * 27 Nov 2015 
    * 
    */ 
    public class JDayChooserExt extends JDayChooser { 

     /** 
     * When false, week-first-day will be painted in red, as in <code>JDayChooser</code>. 
     * When true, week-last-day will be painted in red. 
     */ 
     private boolean isColorWeekend = false; 

     /** 
     * @param weekOfYearVisible 
     */ 
     public JDayChooserExt(boolean weekOfYearVisible) { 

      super(weekOfYearVisible); 
     } 

     /** 
     * Initializes the locale specific names for the days of the week. 
     */ 
     @Override 
     protected void init() { 

      JButton testButton = new JButton(); 
      oldDayBackgroundColor = testButton.getBackground(); 
      selectedColor = new Color(160, 160, 160); 
      drawDayNames(); 
      drawDays(); 

     } 

     /** 
     * Draws the day names of the day columns. 
     */ 
     private void drawDayNames() { 

      DateFormatSymbols dateFormatSymbols = new DateFormatSymbols(locale); 
      dayNames = dateFormatSymbols.getShortWeekdays(); 

      int Day = calendar.getFirstDayOfWeek();//firstDayOfWeek; 

      int coloredDay = (isColorWeekend) ? Day -1 : Day; 
      if(coloredDay <= 0) { 
       coloredDay += 7; 
      } 


      for (int i = 0; i < 7; i++) { 
       if ((maxDayCharacters > 0) && (maxDayCharacters < 5)) { 
        if (dayNames[Day].length() >= maxDayCharacters) { 
         dayNames[Day] = dayNames[Day] 
           .substring(0, maxDayCharacters); 
        } 
       } 

       days[i].setText(dayNames[Day]); 

       if (Day == coloredDay) { 
        days[i].setForeground(sundayForeground); 
       } else { 
        days[i].setForeground(weekdayForeground); 
       } 

       if (Day < 7) { 
        Day++; 
       } else { 
        Day -= 6; 
       } 
      } 
     } 

     /** 
     * @param isColorWeekend the isColorWeekend to set 
     */ 
     public void setColorWeekend(boolean isColorWeekend) { 
      this.isColorWeekend = isColorWeekend; 
     } 


     // /////////////////////////////////////////////////////////// 
     // ////////////// DecoratorButton class ////////////////////// 
     // /////////////////////////////////////////////////////////// 

     class DecoratorButton extends JButton { 
      private static final long serialVersionUID = -5306477668406547496L; 

      public DecoratorButton() { 
       setBackground(decorationBackgroundColor); 
       setContentAreaFilled(decorationBackgroundVisible); 
       setBorderPainted(decorationBordersVisible); 
      } 

      @Override 
      public void addMouseListener(MouseListener l) { 
      } 

      @Override 
      public boolean isFocusable() { 
       return false; 
      } 

      @Override 
      public void paint(Graphics g) { 
       if ("Windows".equals(UIManager.getLookAndFeel().getID())) { 
        // this is a hack to get the background painted 
        // when using Windows Look & Feel 
        if (decorationBackgroundVisible) { 
         g.setColor(decorationBackgroundColor); 
        } else { 
         g.setColor(days[7].getBackground()); 
        } 
        g.fillRect(0, 0, getWidth(), getHeight()); 
        if (isBorderPainted()) { 
         setContentAreaFilled(true); 
        } else { 
         setContentAreaFilled(false); 
        } 
       } 
       super.paint(g); 
      } 
     }; 
    } 
0

我找到了一種方法來實現我需要swingx JXMonthView功能:

public class TestJXChooser extends JFrame { 

    /** 
    * 
    */ 
    public TestJXChooser() { 

     //set locale 
     Locale locale = Locale.forLanguageTag("de-DE"); 

     setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); 

     UIManager.put(CalendarHeaderHandler.uiControllerID, SpinningCalendarHeaderHandler.class.getName()); 
     UIManager.put(SpinningCalendarHeaderHandler.ARROWS_SURROUND_MONTH, Boolean.TRUE); 
     UIManager.put(SpinningCalendarHeaderHandler.FOCUSABLE_SPINNER_TEXT, Boolean.TRUE); 

     final JXMonthView monthView = new JXMonthView(); 
     //needed for the month change and year change arrows 
     monthView.setZoomable(true); 
     monthView.setLocale(locale); 

     //set first day of week to Tuesday 
     monthView.setFirstDayOfWeek(Calendar.TUESDAY); 
     //set Tuesday color 
     monthView.setDayForeground(Calendar.TUESDAY, Color.MAGENTA); 

     getContentPane().add(monthView ); 

     pack(); 
     setVisible(true); 


    } 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 

     new TestJXChooser(); 

    } 
} 

enter image description here 我無法與com.toedter.calendar.JDateChooser去實現它。

1

下面是一個使用反射的骯髒的方式,你只需要重寫JCalendar

private class MyJCalendar extends JCalendar { 

    MyJCalendar(Calendar c) { 
    super(c); 
    } 

    public void setFirstDayOfWeek(int firstdayofweek) { 
    try { 

    // Dirty hack to set first day of week :-) 

    Field f = JDayChooser.class.getDeclaredField("calendar"); 
    f.setAccessible(true); 

    Calendar c = (Calendar) f.get(dayChooser); 
    c.setFirstDayOfWeek(firstdayofweek); 

    Method m = JDayChooser.class.getDeclaredMethod("drawDayNames"); 
    m.setAccessible(true); 
    m.invoke(dayChooser, (Object[])null); 
    m = JDayChooser.class.getDeclaredMethod("drawDays"); 
    m.setAccessible(true);   
    m.invoke(dayChooser, (Object[])null); 

    } catch (Exception ex) { 
    ex.printStackTrace(); 
    } 
    } 
} 
相關問題