/*
* KDay.java
*
* Created on April 5, 2007, 1:22 AM
*
* by John Palermo
* VARRO media
* john.palermo@varromedia.net
*
* class version: 0.9a (r7)
*
*/
package koala.api;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;
import java.awt.GridBagLayout;
import java.awt.Color;
import javax.swing.BorderFactory;
import java.awt.GridBagConstraints;
import koala.components.KCell;
/**
*
* This class builds a calerndar's day pane. She screenshots for examples of
* how the class creates the pane. This class is identical to KBasic.java
* It is replicated and named KDay for ease of understanding. You can equally
* use the KBasic.java class to render the same day pane.
*
* This version is without error handling. It is assumed that the calling
* object sends a proper calArray to this class.
* Rules for well-formed calArrays:
* 1) All the cells in the same row must have the same height.
* 2) The sum of the cell widths in a row must be the same for all rows; that
* is, all rows must have the same total cell width.
*
*
* @author John Palermo
* @version 0.9a (r7)
*
*/
public class KDay extends JPanel implements MouseListener { //ID=KMonthCLASS
//Declare an arrary that will store the cell objects of the calendar
private KCell[][] calendarCellArray;
private String groupThatIsOn; //This represents the ID of cells with the same ID (and form a group) that are currently on
private boolean groupCellsAreOn = false; //This represents whether a group of cells with the same ID are on (true) or are not on (false)
/**
* Creates a new instance of KDay WITHOUT the array parameter that sets the grid of the calendar
*/
public KDay(Color borderColor, int borderThickness, Color backgroundColor) { //ID=KMonthCONSTRUCTOR1
//call the constructor of the super class (JPanel) and make it use the GridBag Layout Manager
super(new GridBagLayout());
//Set the Border with the boderColor and borderThickness
setBorder(BorderFactory.createLineBorder(borderColor,borderThickness));
//Set the Background color with backgroundColor
setBackground(backgroundColor);
//Create a new constraints object
GridBagConstraints c = new GridBagConstraints();
//Set the constraints - make cells as wide and tall as possible in the cells they occupy
c.fill = GridBagConstraints.BOTH;
//Set the constraints - allow cells to stretch both Horizontally and Vertically, so that the entire panel is filled
//when the frame is made larger
//By default all cells with have the same weight, meaning that they will stretch in the same proportions.
c.weightx = 1.0;
c.weighty = 1.0;
} //ID=KMonthCONSTRUCTOR1
/**
* Creates a new instance of KDay WITH the array parameter that sets the grid of the calendar
*/
public KDay(Color borderColor, int borderThickness, Color backgroundColor, String[][][] calArray) { //ID=KMonthCONSTRUCTOR2
//call the constructor of the super class (JPanel) and make it use the GridBag Layout Manager
super(new GridBagLayout());
//Auxiliary variables
int row,col,par;
int save_gridx, save_gridy;
int save_gridwidth, save_gridheight;
//Set the Border with the boderColor and borderThickness
setBorder(BorderFactory.createLineBorder(borderColor,borderThickness));
//Set the Background color with backgroundColor
setBackground(backgroundColor);
//Create a new constraints object
GridBagConstraints c = new GridBagConstraints();
//Set the constraints - make cells as wide and tall as possible in the cells they occupy
c.fill = GridBagConstraints.BOTH;
//Set the constraints - allow cells to stretch both Horizontally and Vertically, so that the entire panel is filled
//when the frame is made larger
//By default all cells with have the same weight, meaning that they will stretch in the same proportions.
c.weightx = 1.0;
c.weighty = 1.0;
//Initialize auxiliary variables
//For the following 2 variables, it is assumed all cells in the same row have the same height
save_gridx = 0; //Used to store the previous cell's x-coordinate; that is, the cell that is to the left and in the same row
save_gridy = 0; //Used to store the previous row's y-coordinate
save_gridwidth = 0; //Used to store the previous cell's width; that is, the width of the cell that is to the left and in the same row
save_gridheight = 0; //Used to store the previous row's height
//Create each cell, one by one, creating the cell as a KCell object
//NOTE: KCell extends VBox_2D which extends JPanel
calendarCellArray = new KCell[calArray.length][];
for (row=0; row < calArray.length; row++) { //ID=FOR_BLOCK1
save_gridx = 0; //reset before each new row
save_gridwidth = 0; //reset before each new row
calendarCellArray[row] = new KCell[calArray[row].length];
for (col=0; col < calArray[row].length; col++) { //ID=FOR_BLOCK1
//Create the calendar cell
calendarCellArray[row][col] = new KCell(calArray[row][col][0], calArray[row][col][1]);
for (par=4; par<calArray[row][col].length; par++) {
switch (par) {
case 4: c.weightx = (calArray[row][col][par].equals("true")) ? 0 : 1; break; //lock the width of the cell if true
case 5: calendarCellArray[row][col].setBorderColor(Color.decode(calArray[row][col][par])); break;
case 6: calendarCellArray[row][col].setOffBackgroundColor(Color.decode(calArray[row][col][par])); break;
case 7: calendarCellArray[row][col].setTextColor(Color.decode(calArray[row][col][par])); break;
case 8: calendarCellArray[row][col].setTextBorderColor(Color.decode(calArray[row][col][par])); break;
case 9: calendarCellArray[row][col].setTextBackgroundColor(Color.decode(calArray[row][col][par])); break;
}
}
//Set the width of the cell (in column units); for example - width of one column, width of two columns;
//Use the analogy of column span in HTML; for example, a cell spans 2 columns (has a columnspan of 2)
c.gridwidth = Integer.decode(calArray[row][col][2]); //use decode to convert String to Integer
//Set the height of the cell (in row units); for example - height of one row, height of two rows;
//Use the analogy of row span in HTML; for example, a cell spans 2 rows (has a rowspan of 2)
c.gridheight = Integer.decode(calArray[row][col][3]); //use decode to convert String to Integer
//NOTE: Since we assume that all cells in a row must have the same height, controlling the height
//of a row by setting c.gridheight for each cell doesn't actually affect the height of the row.
//This is because Java only uses this value to determine if a column should span more than 1 row.
//Java has made this confusing. It should have been named rowspan (like in HTML) instead of
//gridheight. So, just because all the columns in a row actually span 2 rows, it doesn't mean
//that this row that's actually 2 rows looks twice as big as the previous row.
//To make a long story short, in order to acheive what seems to be the height of a row, we
//need to change the weight of the column(s) in the row. This is acheived by setting weighty
//to the height value from calArray[row][col][3]. So for example, if the first row had all
//it's weighty values as 1 and the current (second) row had all it's weighty values as 2 (which
//we call the height of the row), then the second row will LOOK twice as tall as the first row.
//Clear as mud?
c.weighty = c.gridheight;
//The x positon of the current cell should be determined by the previous cell's x postion plus
//the previous cell's cell width
c.gridx = save_gridx + save_gridwidth;
//It is assumed that gridy is the same for all cells in the same row
c.gridy = save_gridy + save_gridheight;
//Save values pertaining to the current column
save_gridx = c.gridx;
save_gridwidth = c.gridwidth;
//Attach the calendar cell to the calendar panel
add(calendarCellArray[row][col],c);
} //ID=FOR_BLOCK2
//Save values pertaining to the current row
save_gridy = c.gridy;
save_gridheight = c.gridheight;
} //ID=FOR_BLOCK1
addMouseListeners();
} //ID=KMonthCONSTRUCTOR2
public String getID(int row, int col) {
String id;
id = calendarCellArray[row][col].getCellID();
return id;
}
public KCell[][] getCalendarCells() {
return calendarCellArray;
}
private void changeState(String ID) {
//Auxiliary variables
int row,col;
if (groupCellsAreOn && !(groupThatIsOn.equals(ID))) { //turn off
groupCellsAreOn = false;
changeState(groupThatIsOn);
}
//change the state of all cells with ID
for (row=0; row<calendarCellArray.length; row++) {
for (col=0; col<calendarCellArray[row].length; col++) {
if (ID == calendarCellArray[row][col].getCellID()) {
if (calendarCellArray[row][col].getState() == "on") { //Set off
calendarCellArray[row][col].setState("off");
calendarCellArray[row][col].setBackgroundColor(calendarCellArray[row][col].getOffColor());
groupCellsAreOn = false;
}
else { //Set on
calendarCellArray[row][col].setState("on");
calendarCellArray[row][col].setBackgroundColor(Color.RED);
groupThatIsOn = calendarCellArray[row][col].getCellID();
groupCellsAreOn = true;
}
}
}
}
}
private void addMouseListeners() {
//Auxiliary variables
int row,col;
//Go through all the calendar cells and add mouse listeners for each
for (row=0; row< calendarCellArray.length; row++) {
for (col=0; col< calendarCellArray[row].length; col++) {
calendarCellArray[row][col].addMouseListener(this);
}
}
}
private void handleEvent(MouseEvent e) {
KCell calendarCell;
calendarCell = (KCell) e.getComponent();
changeState(calendarCell.getCellID());
}
public void mouseClicked(MouseEvent e) {
handleEvent(e);
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
} //ID=KMonthCLASS