1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
| public class WeekPanel extends JPanel {
private static final int CALENDAR_START = Calendar.SEPTEMBER;
private final static Color COLOR_EVEN = new Color(111, 199, 227);
private final static Color COLOR_ODD = Color.WHITE;
private final static Color COLOR_SELECTION = Color.YELLOW;
private final Calendar calendar;
private JLabel[] labels;
private Calendar selection; // la sélection est gérée par un Calendar et non plus un int
private CalendarWeekViewer viewer;
private JPanel weekPanel;
private Map<Integer, Integer> weeks=new HashMap<>(); // on a besoin de retrouver la position d'une semaine dans la liste de label
public WeekPanel(CalendarWeekViewer viewer, Calendar calendar) {
this.viewer=viewer;
this.calendar = calendar;
// comme on ne va plus de la semaine 0 à la dernière, mais d'une semaine en plein milieu de l'année à une autre de l'année suivantre, on ne peut plus utiliser un entier pour la sélection : il est plus simple d'utiliser un calendar (parce qu'on a besoin d'une numéro de la seamine, mais aussi de l'année)
selection = copyCalendar(calendar);
setLayout(new BorderLayout());
Calendar premiereSemaine = getPremiereSemaine(CALENDAR_START);
Calendar derniereSemaine = getDerniereSemaine(CALENDAR_START);
int nbSemaines = compteSemaines(premiereSemaine, derniereSemaine);
labels=new JLabel[nbSemaines];
weekPanel = new JPanel(new GridLayout(1, 0));
Calendar semaine = Calendar.getInstance(); // on a besoin de parcourir les semaines...
semaine.setTime(premiereSemaine.getTime()); // on les parcourt de la première à la dernière
for(int i=0; i<nbSemaines; i++) {
final Calendar week = copyCalendar(semaine);
weeks.put(week.get(Calendar.WEEK_OF_YEAR), i); // ceci nous permet de facilement trouver le numéro d'une semaine dans la liste de label
JLabel label = new JLabel(getWeekLabel(semaine), JLabel.CENTER);
label.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
label.setOpaque(true);
labels[i]=label;
setLabelColor(week);
label.setEnabled(true);
label.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
setSelection(week);
}
});
weekPanel.add(label);
semaine.add(Calendar.WEEK_OF_YEAR, 1); // on avance d'une semaine
}
JScrollPane slider = new JScrollPane(weekPanel,
JScrollPane.VERTICAL_SCROLLBAR_NEVER,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
add(slider, BorderLayout.CENTER);
}
private Calendar copyCalendar(Calendar calendar) {
Calendar copy = Calendar.getInstance();
copy.setTime(calendar.getTime());
return copy;
}
private int compteSemaines(Calendar premiereSemaine,
Calendar derniereSemaine) {
Calendar calendar = copyCalendar(premiereSemaine); // on prend une nouvelle instance
int count=0;
while(calendar.get(Calendar.WEEK_OF_YEAR)!=derniereSemaine.get(Calendar.WEEK_OF_YEAR)) { // tant qu'on a pas atteint la dernière semaine
count++; // on compte une semaine de plus
calendar.add(Calendar.WEEK_OF_YEAR, 1); // on avance d'une semaine
}
return count + 1; // on ajoute 1 parce qu'il faut compte la dernière semaine (qu'on a pas compter dans la boucle)
}
public static Calendar getPremiereSemaine(int month) {
Calendar calendar = Calendar.getInstance();
// le calendar à l'initialisation contient la date du jour
int currentmonth = calendar.get(Calendar.MONTH);
if ( currentmonth<CALENDAR_START ) { // si le mois courant est avant septembre
// on doit passer à l'année d'avant pour commencer en septembre
calendar.add(Calendar.YEAR, -1);
}
calendar.set(Calendar.MONTH,month); // on se positionne sur le mois demandé
calendar.set(Calendar.WEEK_OF_MONTH, 1); // on se positionne sur la première semaine du mois
calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek()); // on se positionne sur le premier jour officiel
return calendar;
}
public static Calendar getDerniereSemaine(int month) {
Calendar calendar = getPremiereSemaine(month); // on se place sur la première semaine du mois
calendar.add(Calendar.YEAR, 1); // on avance d'un an
calendar.add(Calendar.WEEK_OF_YEAR, -1); // on recule d'une semaine
return calendar;
}
private void setLabelColor(Calendar calendar) {
JLabel label=labels[weeks.get(calendar.get(Calendar.WEEK_OF_YEAR))]; // on utilise la map pour savoir le numéro du label correspondant à la semaine
if ( calendar.equals(selection) ) {
label.setBackground(COLOR_SELECTION); // la semaine sélectionnée
}
else if (calendar.get(Calendar.WEEK_OF_YEAR) % 2 == 0) { // les semaines impaires d'une couleur
label.setBackground(COLOR_ODD);
} else {
label.setBackground(COLOR_EVEN); // les paires d'une autre
}
}
public void updateSelection() {
Calendar oldSelection = selection;
selection = copyCalendar(calendar);
setLabelColor(oldSelection);
setLabelColor(selection);
weekPanel.scrollRectToVisible(labels[weeks.get(selection.get(Calendar.WEEK_OF_YEAR))].getBounds());
}
private void setSelection(Calendar selection) {
Calendar oldSelection = this.selection;
this.selection = selection;
setLabelColor(oldSelection);
setLabelColor(selection);
viewer.setWeek(selection);
}
private String getWeekLabel(Calendar week) {
Calendar calendar = copyCalendar(week);
// le premier jour de cette semaine
Date premierJour = calendar.getTime();
int monthPremierJour = calendar.get(Calendar.MONTH);
// le dernier jour de cette semaine
calendar.add(Calendar.WEEK_OF_YEAR, 1);
calendar.add(Calendar.DAY_OF_WEEK, -1);
Date dernierJour = calendar.getTime();
int monthDernierJour = calendar.get(Calendar.MONTH);
return getWeekLabel(week.get(Calendar.WEEK_OF_YEAR), premierJour, dernierJour, monthPremierJour, monthDernierJour);
}
private final static DateFormat DATE_DEBUT_FORMAT = new SimpleDateFormat(
"dd");
private final static DateFormat DATE_FORMAT = new SimpleDateFormat(
"dd MMMM");
public static String getWeekLabel(int week, Date premierJour, Date dernierJour, int monthPremierJour, int monthDernierJour) {
String debut;
if (monthDernierJour == monthPremierJour) {
debut = DATE_DEBUT_FORMAT.format(premierJour);
} else {
debut = DATE_FORMAT.format(premierJour);
}
String milieu = DATE_FORMAT.format(dernierJour);
String fin = " (" + week + ")";
return debut + " - " + milieu + fin;
}
} |
Partager