Java 如何在JCalendar中设置自定义周开始?
我在JCalendar设置一周的第一天自定义时遇到问题。 如果我改变了地点,一周的第一天就会改变。 但是,在基础日历中更改一周的第一天不会产生任何效果 下面是一个简短的演示代码:Java 如何在JCalendar中设置自定义周开始?,java,swing,calendar,locale,jcalendar,Java,Swing,Calendar,Locale,Jcalendar,我在JCalendar设置一周的第一天自定义时遇到问题。 如果我改变了地点,一周的第一天就会改变。 但是,在基础日历中更改一周的第一天不会产生任何效果 下面是一个简短的演示代码: public class TestJChooser extends JFrame { /** * */ public TestJChooser() { setLayout(new BorderLayout(5,5)); setDefaultClos
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中一周的第一天,也不会更改周末。我找到了一种方法来实现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();
}
}
我无法使用com.toedter.calendar.JDateChooser实现它。为了实现使用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();
}
}
结果可以在图像中看到
第二幅图演示如何将一周的第一天设置为星期二
延长了两个班。扩展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);
}
};
}
下面是使用反射的肮脏方式,您只需覆盖
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();
}
}
}
同样的问题,从2013年起没有真正的答案: