12d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// © 2016 and later: Unicode, Inc. and others. 22d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License 3bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert/* 4bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert ******************************************************************************* 5bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * Copyright (C) 1996-2014, International Business Machines Corporation and * 6bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * others. All Rights Reserved. * 7bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert ******************************************************************************* 8bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */ 9bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 10bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertpackage com.ibm.icu.dev.demo.holiday; 11bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 12bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.BorderLayout; 13bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.Button; 14bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.Canvas; 15bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.Choice; 16bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.Color; 17bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.Component; 18bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.Container; 19bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.Dimension; 20bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.Font; 21bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.FontMetrics; 22bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.Frame; 23bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.Graphics; 24bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.GridBagConstraints; 25bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.GridBagLayout; 26bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.Label; 27bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.Panel; 28bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.Point; 29bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.event.ActionEvent; 30bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.event.ActionListener; 31bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.event.ItemEvent; 32bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.event.ItemListener; 33bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.awt.event.WindowEvent; 34bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.text.DateFormatSymbols; 35bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.Date; 36bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.Locale; 37bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport java.util.Vector; 38bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 39bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.ibm.icu.dev.demo.impl.DemoApplet; 40bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.ibm.icu.dev.demo.impl.DemoTextBox; 41bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.ibm.icu.dev.demo.impl.DemoUtility; 42bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.ibm.icu.text.DateTimePatternGenerator; 43bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.ibm.icu.text.SimpleDateFormat; 44bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.ibm.icu.util.Calendar; 45bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertimport com.ibm.icu.util.Holiday; 46bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 47bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert/** 48bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * CalendarDemo demonstrates how Calendar works. 49bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */ 50bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubertpublic class HolidayCalendarDemo extends DemoApplet 51bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert{ 52bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert /** 53bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * For serialization 54bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */ 55bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private static final long serialVersionUID = 4546085430817359372L; 56bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 57bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert /** 58bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * The main function which defines the behavior of the CalendarDemo 59bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * applet when an applet is started. 60bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */ 61bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public static void main(String argv[]) { 62bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 63bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert new HolidayCalendarDemo().showDemo(); 64bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 65bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 66bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert /* This creates a CalendarFrame for the demo applet. */ 67bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public Frame createDemoFrame(DemoApplet applet) { 68bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return new CalendarFrame(applet); 69bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 70bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 71bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert /** 72bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * A Frame is a top-level window with a title. The default layout for a frame 73bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * is BorderLayout. The CalendarFrame class defines the window layout of 74bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * CalendarDemo. 75bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */ 76bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private static class CalendarFrame extends Frame implements ActionListener, 77bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert ItemListener 78bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 79bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert /** 80bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * For serialization 81bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */ 82bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private static final long serialVersionUID = -7023296782393042761L; 83bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 84bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private static final boolean DEBUG = false; 85bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 86bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert //private Locale curLocale = Locale.US; // unused 87bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 88bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private DemoApplet applet; 89bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 90bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private static final Locale[] calendars = { 91bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert //new Locale("de","AT"), 92bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Locale.CANADA, 93bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Locale.CANADA_FRENCH, 94bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Locale.FRANCE, 95bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Locale.GERMANY, 96bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert new Locale("iw","IL"), 97bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert new Locale("el","GR"), 98bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert //new Locale("es","MX"), 99bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Locale.UK, 100bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Locale.US, 101bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert }; 102bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private static final Locale[] displays = { 103bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Locale.CANADA, 104bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Locale.UK, 105bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Locale.US, 106bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Locale.FRANCE, 107bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Locale.CANADA_FRENCH, 108bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert //new Locale("de","AT"), 109bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Locale.GERMAN, 110bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert new Locale("el","GR"), 111bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert //new Locale("iw","IL"), 112bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert new Locale("es","MX"), 113bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert }; 114bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 115bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert /** 116bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * Constructs a new CalendarFrame that is initially invisible. 117bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */ 118bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public CalendarFrame(DemoApplet applet) 119bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 120bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert super("Calendar Demo"); 121bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.applet = applet; 122bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert init(); 123bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert start(); 124bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert enableEvents(WindowEvent.WINDOW_CLOSING); 125bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 126bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 127bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert /** 128bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * Initializes the applet. You never need to call this directly, it 129bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * is called automatically by the system once the applet is created. 130bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */ 131bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void init() 132bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 133bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Get G7 locales only for demo purpose. To get all the locales 134bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // supported, switch to calling Calendar.getAvailableLocales(). 135bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // commented 136bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert locales = displays; 137bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 138bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert buildGUI(); 139bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 140bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 141bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert //------------------------------------------------------------ 142bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // package private 143bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert //------------------------------------------------------------ 144bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert void addWithFont(Container container, Component foo, Font font) { 145bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (font != null) 146bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert foo.setFont(font); 147bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert container.add(foo); 148bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 149bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 150bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert /** 151bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * Called to start the applet. You never need to call this method 152bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * directly, it is called when the applet's document is visited. 153bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */ 154bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void start() 155bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 156bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // do nothing 157bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 158bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 159bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private Choice localeMenu; 160bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private Choice displayMenu; 161bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private Locale[] locales; 162bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 163bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private Label monthLabel; 164bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private Button prevYear; 165bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private Button prevMonth; 166bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private Button gotoToday; 167bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private Button nextMonth; 168bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private Button nextYear; 169bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private CalendarPanel calendarPanel; 170bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 171bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private static final Locale kFirstLocale = Locale.US; 172bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 173bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private static void add(Container container, Component component, 174bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert GridBagLayout g, GridBagConstraints c) 175bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 176bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.setConstraints(component, c); 177bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert container.add(component); 178bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 179bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 180bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void buildGUI() 181bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 182bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert setBackground(DemoUtility.bgColor); 183bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert setLayout(new BorderLayout(10,10)); 184bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 185bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Label for the demo's title 186bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Label titleLabel = new Label("Calendar Demo", Label.CENTER); 187bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert titleLabel.setFont(DemoUtility.titleFont); 188bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 189bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Label for the current month name 190bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert monthLabel = new Label("", Label.LEFT); 191bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert monthLabel.setFont(new Font(DemoUtility.titleFont.getName(), 192bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert DemoUtility.titleFont.getStyle(), 193bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert (DemoUtility.titleFont.getSize() * 3)/2)); 194bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 195bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Make the locale popup menus 196bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert localeMenu= new Choice(); 197bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert localeMenu.addItemListener(this); 198bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int selectMe = 0; 199bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 200bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int i = 0; i < calendars.length; i++) { 201bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (i > 0 && 202bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert calendars[i].getCountry().equals(calendars[i-1].getCountry()) || 203bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert i < calendars.length - 1 && 204bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert calendars[i].getCountry().equals(calendars[i+1].getCountry())) 205bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 206bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert localeMenu.addItem(calendars[i].getDisplayCountry() + " (" + 207bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert calendars[i].getDisplayLanguage() + ")"); 208bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } else { 209bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert localeMenu.addItem( calendars[i].getDisplayCountry() ); 210bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 211bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 212bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (calendars[i].equals(kFirstLocale)) { 213bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert selectMe = i; 214bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 215bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 216bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 217bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert localeMenu.setBackground(DemoUtility.choiceColor); 218bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert localeMenu.select(selectMe); 219bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 220bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert displayMenu = new Choice(); 221bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert displayMenu.addItemListener(this); 222bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 223bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert selectMe = 0; 224bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int i = 0; i < locales.length; i++) { 225bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (i > 0 && 226bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert locales[i].getLanguage().equals(locales[i-1].getLanguage()) || 227bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert i < locales.length - 1 && 228bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert locales[i].getLanguage().equals(locales[i+1].getLanguage())) 229bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 230bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert displayMenu.addItem( locales[i].getDisplayName() ); 231bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } else { 232bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert displayMenu.addItem( locales[i].getDisplayLanguage()); 233bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 234bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 235bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (locales[i].equals(kFirstLocale)) { 236bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert selectMe = i; 237bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 238bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 239bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 240bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert displayMenu.setBackground(DemoUtility.choiceColor); 241bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert displayMenu.select(selectMe); 242bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 243bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Make all the next/previous/today buttons 244bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert prevYear = new Button("<<"); 245bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert prevYear.addActionListener(this); 246bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert prevMonth = new Button("<"); 247bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert prevMonth.addActionListener(this); 248bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert gotoToday = new Button("Today"); 249bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert gotoToday.addActionListener(this); 250bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert nextMonth = new Button(">"); 251bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert nextMonth.addActionListener(this); 252bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert nextYear = new Button(">>"); 253bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert nextYear.addActionListener(this); 254bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 255bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // The month name and the control buttons are bunched together 256bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Panel monthPanel = new Panel(); 257bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 258bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert GridBagLayout g = new GridBagLayout(); 259bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert GridBagConstraints c = new GridBagConstraints(); 260bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert monthPanel.setLayout(g); 261bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 262bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.weightx = 1; 263bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.weighty = 1; 264bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 265bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.gridwidth = 1; 266bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.fill = GridBagConstraints.HORIZONTAL; 267bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.gridwidth = GridBagConstraints.REMAINDER; 268bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert add(monthPanel, monthLabel, g, c); 269bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 270bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.gridwidth = 1; 271bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert add(monthPanel, prevYear, g, c); 272bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert add(monthPanel, prevMonth, g, c); 273bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert add(monthPanel, gotoToday, g, c); 274bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert add(monthPanel, nextMonth, g, c); 275bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.gridwidth = GridBagConstraints.REMAINDER; 276bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert add(monthPanel, nextYear, g, c); 277bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 278bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 279bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Stick the menu and buttons in a little "control panel" 280bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Panel menuPanel = new Panel(); 281bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 282bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert GridBagLayout g = new GridBagLayout(); 283bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert GridBagConstraints c = new GridBagConstraints(); 284bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert menuPanel.setLayout(g); 285bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 286bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.weightx = 1; 287bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.weighty = 1; 288bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 289bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.fill = GridBagConstraints.HORIZONTAL; 290bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 291bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.gridwidth = GridBagConstraints.RELATIVE; 292bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Label l1 = new Label("Holidays"); 293bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert l1.setFont(DemoUtility.labelFont); 294bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert add(menuPanel, l1, g, c); 295bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 296bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.gridwidth = GridBagConstraints.REMAINDER; 297bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert add(menuPanel, localeMenu, g, c); 298bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 299bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.gridwidth = GridBagConstraints.RELATIVE; 300bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Label l2 = new Label("Display:"); 301bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert l2.setFont(DemoUtility.labelFont); 302bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert add(menuPanel, l2, g, c); 303bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 304bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.gridwidth = GridBagConstraints.REMAINDER; 305bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert add(menuPanel, displayMenu, g, c); 306bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 307bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 308bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // The title, buttons, etc. go in a panel at the top of the window 309bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Panel topPanel = new Panel(); 310bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 311bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert topPanel.setLayout(new BorderLayout()); 312bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 313bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert //topPanel.add("North", titleLabel); 314bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert topPanel.add("Center", monthPanel); 315bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert topPanel.add("East", menuPanel); 316bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 317bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert add("North", topPanel); 318bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 319bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // The copyright notice goes at the bottom of the window 320bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Label copyright = new Label(DemoUtility.copyright1, Label.LEFT); 321bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert copyright.setFont(DemoUtility.creditFont); 322bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert add("South", copyright); 323bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 324bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Now create the big calendar panel and stick it in the middle 325bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert calendarPanel = new CalendarPanel( kFirstLocale ); 326bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert add("Center", calendarPanel); 327bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 328bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert updateMonthName(); 329bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 330bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 331bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private void updateMonthName() 332bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 333bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final Locale displayLocale = calendarPanel.getDisplayLocale(); 334bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert final String pattern = DateTimePatternGenerator. 335bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert getInstance(displayLocale).getBestPattern("MMMMy"); 336bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert SimpleDateFormat f = new SimpleDateFormat(pattern, 337bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert displayLocale); 338bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert f.setCalendar(calendarPanel.getCalendar()); 339bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert monthLabel.setText( f.format( calendarPanel.firstOfMonth() )); 340bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 341bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 342bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert /** 343bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * Handles the event. Returns true if the event is handled and should not 344bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * be passed to the parent of this component. The default event handler 345bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * calls some helper methods to make life easier on the programmer. 346bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */ 347bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void actionPerformed(ActionEvent e) 348bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 349bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Object obj = e.getSource(); 350bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 351bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // *** Button events are handled here. 352bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (obj instanceof Button) { 353bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (obj == nextMonth) { 354bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert calendarPanel.add(Calendar.MONTH, +1); 355bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 356bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert else 357bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (obj == prevMonth) { 358bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert calendarPanel.add(Calendar.MONTH, -1); 359bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 360bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert else 361bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (obj == prevYear) { 362bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert calendarPanel.add(Calendar.YEAR, -1); 363bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 364bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert else 365bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (obj == nextYear) { 366bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert calendarPanel.add(Calendar.YEAR, +1); 367bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 368bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert else 369bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (obj == gotoToday) { 370bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert calendarPanel.set( new Date() ); 371bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 372bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert updateMonthName(); 373bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 374bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 375bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 376bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void itemStateChanged(ItemEvent e) 377bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 378bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Object obj = e.getSource(); 379bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (obj == localeMenu) { 380bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert calendarPanel.setCalendarLocale(calendars[localeMenu.getSelectedIndex()]); 381bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert updateMonthName(); 382bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 383bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert else 384bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (obj == displayMenu) { 385bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert calendarPanel.setDisplayLocale(locales[displayMenu.getSelectedIndex()]); 386bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert updateMonthName(); 387bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 388bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 389bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 390bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert /** 391bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * Print out the error message while debugging this program. 392bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */ 393bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void errorText(String s) 394bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 395bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (DEBUG) 396bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 397bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert System.out.println(s); 398bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 399bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 400bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 401bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert protected void processWindowEvent(WindowEvent e) 402bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 403bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert System.out.println("event " + e); 404bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (e.getID() == WindowEvent.WINDOW_CLOSING) { 405bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.hide(); 406bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.dispose(); 407bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 408bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (applet != null) { 409bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert applet.demoClosed(); 410bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } else { 411bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert System.exit(0); 412bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 413bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 414bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 415bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 416bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 417bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 418bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private static class CalendarPanel extends Canvas { 419bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 420bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert /** 421bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * For serialization 422bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */ 423bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private static final long serialVersionUID = 1521099412250120821L; 424bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 425bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public CalendarPanel( Locale locale ) { 426bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert set(locale, locale, new Date()); 427bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 428bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 429bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void setCalendarLocale(Locale locale) { 430bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert set(locale, fDisplayLocale, fCalendar.getTime()); 431bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 432bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 433bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void setDisplayLocale(Locale locale) { 434bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert set(fCalendarLocale, locale, fCalendar.getTime()); 435bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 436bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 437bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void set(Date date) { 438bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert set(fCalendarLocale, fDisplayLocale, date); 439bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 440bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 441bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void set(Locale loc, Locale display, Date date) 442bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 443bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (fCalendarLocale == null || !loc.equals(fCalendarLocale)) { 444bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fCalendarLocale = loc; 445bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fCalendar = Calendar.getInstance(fCalendarLocale); 446bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fAllHolidays = Holiday.getHolidays(fCalendarLocale); 447bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 448bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (fDisplayLocale == null || !display.equals(fDisplayLocale)) { 449bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fDisplayLocale = display; 450bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fSymbols = new DateFormatSymbols(fDisplayLocale); 451bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 452bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 453bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fStartOfMonth = date; 454bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 455bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert dirty = true; 456bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert repaint(); 457bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 458bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 459bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void add(int field, int delta) 460bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 461bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert synchronized(fCalendar) { 462bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fCalendar.setTime(fStartOfMonth); 463bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fCalendar.add(field, delta); 464bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fStartOfMonth = fCalendar.getTime(); 465bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 466bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert dirty = true; 467bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert repaint(); 468bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 469bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 470bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public com.ibm.icu.util.Calendar getCalendar() { 471bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return fCalendar; 472bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 473bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 474bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public Locale getCalendarLocale() { 475bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return fCalendarLocale; 476bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 477bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 478bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public Locale getDisplayLocale() { 479bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return fDisplayLocale; 480bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 481bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 482bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 483bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public Date firstOfMonth() { 484bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return fStartOfMonth; 485bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 486bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 487bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private Date startOfMonth(Date dateInMonth) 488bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 489bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert synchronized(fCalendar) { 490bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fCalendar.setTime(dateInMonth); // TODO: synchronization 491bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 492bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int era = fCalendar.get(Calendar.ERA); 493bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int year = fCalendar.get(Calendar.YEAR); 494bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int month = fCalendar.get(Calendar.MONTH); 495bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 496bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fCalendar.clear(); 497bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fCalendar.set(Calendar.ERA, era); 498bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fCalendar.set(Calendar.YEAR, year); 499bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fCalendar.set(Calendar.MONTH, month); 500bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fCalendar.set(Calendar.DATE, 1); 501bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 502bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return fCalendar.getTime(); 503bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 504bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 505bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 506bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private void calculate() 507bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 508bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Calendar c = (Calendar)fCalendar.clone(); // Temporary copy 509bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 510bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fStartOfMonth = startOfMonth(fStartOfMonth); 511bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 512bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Stash away a few useful constants for this calendar and display 513bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert minDay = c.getMinimum(Calendar.DAY_OF_WEEK); 514bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert daysInWeek = c.getMaximum(Calendar.DAY_OF_WEEK) - minDay + 1; 515bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 516bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert firstDayOfWeek = Calendar.getInstance(fDisplayLocale).getFirstDayOfWeek(); 517bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 518bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Stash away a Date for the start of this month 519bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 520bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Find the day of week of the first day in this month 521bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.setTime(fStartOfMonth); 522bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert firstDayInMonth = c.get(Calendar.DAY_OF_WEEK); 523bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 524bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Now find the # of days in the month 525bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.roll(Calendar.DATE, false); 526bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert daysInMonth = c.get(Calendar.DATE); 527bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 528bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Finally, find the end of the month, i.e. the start of the next one 529bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.roll(Calendar.DATE, true); 530bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.add(Calendar.MONTH, 1); 531bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.getTime(); // JDK 1.1.2 bug workaround 532bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.add(Calendar.SECOND, -1); 533bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Date endOfMonth = c.getTime(); 534bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 535bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // 536bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Calculate the number of full or partial weeks in this month. 537bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // To do this I can just reuse the code that calculates which 538bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // calendar cell contains a given date. 539bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // 540bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert numWeeks = dateToCell(daysInMonth).y - dateToCell(1).y + 1; 541bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 542bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Remember which holidays fall on which days in this month, 543bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // to save the trouble of having to do it later 544bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fHolidays.setSize(0); 545bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 546bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int h = 0; h < fAllHolidays.length; h++) 547bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 548bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Date d = fStartOfMonth; 549bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert while ( (d = fAllHolidays[h].firstBetween(d, endOfMonth) ) != null) 550bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 551bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if(d.after(endOfMonth)) { 552bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert throw new InternalError("Error: for " + fAllHolidays[h].getDisplayName()+ 553bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert " #" + h + "/"+fAllHolidays.length+": " + d +" is after end of month " + endOfMonth); 554bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 555bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.setTime(d); 556bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fHolidays.addElement( new HolidayInfo(c.get(Calendar.DATE), 557bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fAllHolidays[h], 558bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fAllHolidays[h].getDisplayName(fDisplayLocale) )); 559bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 560bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert d.setTime( d.getTime() + 1000 ); // "d++" 561bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 562bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 563bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert dirty = false; 564bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 565bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 566bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert static final int INSET = 2; 567bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 568bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert /* 569bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * Convert from the day number within a month (1-based) 570bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert * to the cell coordinates on the calendar (0-based) 571bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert */ 572bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private void dateToCell(int date, Point pos) 573bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 574bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int cell = (date + firstDayInMonth - firstDayOfWeek - minDay); 575bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (firstDayInMonth < firstDayOfWeek) { 576bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert cell += daysInWeek; 577bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 578bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 579bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert pos.x = cell % daysInWeek; 580bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert pos.y = cell / daysInWeek; 581bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 582bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private Point dateToCell(int date) { 583bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Point p = new Point(0,0); 584bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert dateToCell(date, p); 585bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert return p; 586bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 587bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 588bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public void paint(Graphics g) { 589bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 590bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (dirty) { 591bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert calculate(); 592bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 593bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 594bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Point cellPos = new Point(0,0); // Temporary variable 595bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Dimension d = getSize(); 596bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 597bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.setColor(DemoUtility.bgColor); 598bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.fillRect(0,0,d.width,d.height); 599bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 600bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Draw the day names at the top 601bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.setColor(Color.black); 602bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.setFont(DemoUtility.labelFont); 603bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert FontMetrics fm = g.getFontMetrics(); 604bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int labelHeight = fm.getHeight() + INSET * 2; 605bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 606bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int v = fm.getAscent() + INSET; 607bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int i = 0; i < daysInWeek; i++) { 608bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int dayNum = (i + minDay + firstDayOfWeek - 2) % daysInWeek + 1; 609bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert String dayName = fSymbols.getWeekdays()[dayNum]; 610bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 611bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int h = (int) (d.width * (i + 0.5)) / daysInWeek; 612bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert h -= fm.stringWidth(dayName) / 2; 613bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 614bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.drawString(dayName, h, v); 615bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 616bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 617bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert double cellHeight = (d.height - labelHeight - 1) / numWeeks; 618bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert double cellWidth = (double)(d.width - 1) / daysInWeek; 619bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 620bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Draw a white background in the part of the calendar 621bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // that displays this month. 622bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // First figure out how much of the first week should be shaded. 623bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 624bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.setColor(Color.white); 625bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert dateToCell(1, cellPos); 626bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int width = (int)(cellPos.x*cellWidth); // Width of unshaded area 627bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 628bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.fillRect((int)(width), labelHeight , 629bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert (int)(d.width - width), (int)cellHeight); 630bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 631bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // All of the intermediate weeks get shaded completely 632bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.fillRect(0, (int)(labelHeight + cellHeight), 633bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert d.width, (int)(cellHeight * (numWeeks - 2))); 634bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 635bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Now figure out the last week. 636bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert dateToCell(daysInMonth, cellPos); 637bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert width = (int)((cellPos.x+1)*cellWidth); // Width of shaded area 638bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 639bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.fillRect(0, (int)(labelHeight + (numWeeks-1) * cellHeight), 640bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert width, (int)(cellHeight)); 641bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 642bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 643bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Draw the X/Y grid lines 644bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.setColor(Color.black); 645bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int i = 0; i <= numWeeks; i++) { 646bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int y = (int)(labelHeight + i * cellHeight); 647bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.drawLine(0, y, d.width - 1, y); 648bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 649bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int i = 0; i <= daysInWeek; i++) { 650bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int x = (int)(i * cellWidth); 651bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.drawLine(x, labelHeight, x, d.height - 1); 652bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 653bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 654bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Now loop through all of the days in the month, figure out where 655bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // they go in the grid, and draw the day # for each one 656bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Font numberFont = new Font("Helvetica",Font.PLAIN,12); 657bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // not used Font holidayFont = DemoUtility.creditFont; 658bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 659bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert Calendar c = (Calendar)fCalendar.clone(); 660bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert c.setTime(fStartOfMonth); 661bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 662bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert for (int i = 1, h = 0; i <= daysInMonth; i++) { 663bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.setFont(numberFont); 664bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.setColor(Color.black); 665bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert fm = g.getFontMetrics(); 666bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 667bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert dateToCell(i, cellPos); 668bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int x = (int)((cellPos.x + 1) * cellWidth); 669bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert int y = (int)(cellPos.y * cellHeight + labelHeight); 670bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 671bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert StringBuffer buffer = new StringBuffer(); 672bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert buffer.append(i); 673bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert String dayNum = buffer.toString(); 674bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 675bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert x = x - INSET - fm.stringWidth(dayNum); 676bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert y = y + fm.getAscent() + INSET; 677bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 678bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.drawString(dayNum, x, y); 679bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 680bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // See if any of the holidays land on this day.... 681bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert HolidayInfo info = null; 682bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 683bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Coordinates of lower-left corner of cell. 684bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert x = (int)((cellPos.x) * cellWidth); 685bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert y = (int)((cellPos.y+1) * cellHeight) + labelHeight; 686bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 687bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert while (h < fHolidays.size() && 688bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert (info = (HolidayInfo)fHolidays.elementAt(h)).date <= i) 689bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert { 690bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert if (info.date == i) { 691bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Draw the holiday here. 692bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.setFont(numberFont); 693bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert g.setColor(Color.red); 694bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 695bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert DemoTextBox box = new DemoTextBox(g, info.name, (int)(cellWidth - INSET)); 696bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert box.draw(g, x + INSET, y - INSET - box.getHeight()); 697bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 698bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert y -= (box.getHeight() + INSET); 699bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 700bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert h++; 701bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 702bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 703bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 704bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 705bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Important state variables 706bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private Locale fCalendarLocale; // Whose calendar 707bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private Calendar fCalendar; // Calendar for calculations 708bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 709bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private Locale fDisplayLocale; // How to display it 710bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private DateFormatSymbols fSymbols; // Symbols for drawing 711bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 712bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private Date fStartOfMonth; // 00:00:00 on first day of month 713bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 714bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert // Cached calculations to make drawing faster. 715bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private transient int minDay; // Minimum legal day # 716bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private transient int daysInWeek; // # of days in a week 717bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private transient int firstDayOfWeek; // First day to display in week 718bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private transient int numWeeks; // # full or partial weeks in month 719bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private transient int daysInMonth; // # days in this month 720bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private transient int firstDayInMonth; // Day of week of first day in month 721bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 722bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private transient Holiday[] fAllHolidays; 723bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private transient Vector fHolidays = new Vector(5,5); 724bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 725bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private transient boolean dirty = true; 726bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 727bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 728bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert private static class HolidayInfo { 729bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public HolidayInfo(int date, Holiday holiday, String name) { 730bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.date = date; 731bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.holiday = holiday; 732bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert this.name = name; 733bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 734bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 735bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public Holiday holiday; 736bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public int date; 737bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert public String name; 738bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert } 739bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert} 740bd1cbb618dcaa1ac6ba7c77dece35cb79593a5d7Fredrik Roubert 741