/** * @(#)JCalendar.java 0.1 28/06/2002 * * Copyright (c) 2002 Arron Ferguson * */ package ca.bcit.geekkit; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; /** * <p> * <code>JCalendar</code> is a complex widget that keeps track of a calendar. It uses its own customized * <code>TableModel</code> for keeping track of specific dates that may require custom rendrering other than the usual * number being in each cell. * </p> * * @version 0.1 28/06/2002 * @author Arron Ferguson */ public class JCalendar extends JPanel implements ActionListener { /** * For clicking on to take the calendar to the next month */ private JButton nextButton; /** * For clicking on to take the calendar to the previous month */ private JButton previousButton; /** * Displays the month and the year inside of the calendar layout */ protected JLabel label; /** * The set of rows and columns used to display dates. */ protected JTable table; /** * Layout that allows for a grid like layout pattern. Components do not have to take up exactly one cell, instead * they can take up more than one row or column. */ private GraphPaperLayout gp; /** * A custom <code>TableModel</code> for dealing with specifically calendar like cells */ private CalendarTableModel model; private final Class tableClass; /** * Default constructor */ public JCalendar() { this( JCalendarTable.class ); } public JCalendar( final Class tableClass ) { super(); this.tableClass = tableClass; this.configUI(); this.nextButton.addActionListener( this ); this.previousButton.addActionListener( this ); } /** * Configures the UI and sets up the renderers */ private void configUI() { this.gp = new GraphPaperLayout( new Dimension( 8, 10 ) ); this.setLayout( this.gp ); this.nextButton = new JButton( "Next" ); this.previousButton = new JButton( "Back" ); this.label = new JLabel( "", SwingConstants.CENTER ); this.model = new CalendarTableModel( this ); this.initializeTable(); this.table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF ); // don't allow rows or columns to be selected this.table.setCellSelectionEnabled( true ); this.table.setColumnSelectionAllowed( false ); this.table.setRowSelectionAllowed( false ); // don't allow cells to be selected this.table.setFocusable( true ); // little bit of customization of cell renderers JLabel cell = (JLabel) this.table.getDefaultRenderer( JLabel.class ); cell.setHorizontalAlignment( SwingConstants.LEFT ); cell.setVerticalAlignment( SwingConstants.TOP ); this.table.getTableHeader().setReorderingAllowed( false ); // add buttons this.add( this.previousButton, new Rectangle( 0, 0, 2, 1 ) ); this.add( this.nextButton, new Rectangle( 6, 0, 2, 1 ) ); // add label this.add( this.label, new Rectangle( 2, 0, 4, 1 ) ); this.add( this.table.getTableHeader(), new Rectangle( 0, 2, 8, 1 ) ); this.add( this.table, new Rectangle( 0, 3, 8, 7 ) ); // now call it for a populate this.model.generateCalendarMonth( 0 ); } /** * Handles the two <code>JButton</code>s events for going forward and backward in the years * * @param e the <code>ActionEvent</code> given. */ public void actionPerformed( final ActionEvent e ) { if ( e.getSource() == this.nextButton ) { this.model.generateCalendarMonth( 1 ); } else if ( e.getSource() == this.previousButton ) { this.model.generateCalendarMonth( -1 ); } } /** * Custom paint to allow cells to change height based on the size of the <code>Container</code> that the table is * in * * @param g the <code>Graphics</code> context used to paint the table. */ @Override public void paint( final Graphics g ) { super.paint( g ); // make row height resize as the component is resized so that rows fill up the space float componentHeight = this.table.getHeight(); float numberofRows = this.table.getRowCount(); float tableCellHeight = componentHeight / numberofRows; int height = (int) tableCellHeight; this.table.setRowHeight( height ); } /** * Returns the preferred size of this composite component * * @return the width and height of this component as a <code>Dimension</code> object and as its preferred size to * be rendered. */ @Override public Dimension getPreferredSize() { return new Dimension( 310, 220 ); } /** * Returns the minimum size that this composite component should be drawn at * * @return the minimum width and height that this component should be rendered at */ @Override public Dimension getMinimumSize() { return new Dimension( 260, 170 ); } public JTable getTable() { return this.table; } public CalendarTableModel getModel() { return this.model; } private void initializeTable() { try { if ( JTable.class.isAssignableFrom( this.tableClass ) ) { Object[] parameters = new Object[ 1 ]; parameters[ 0 ] = this.model; Class[] parameterTypes = new Class[ 1 ]; parameterTypes[ 0 ] = CalendarTableModel.class; this.table = (JTable) this.tableClass.getConstructor( parameterTypes ).newInstance( parameters ); } } catch ( Exception e ) { } if ( this.table == null ) { this.table = new JCalendarTable( this.model ); } } public class JCalendarTable extends JTable { private final DefaultTableCellRenderer highlighter; public JCalendarTable( final CalendarTableModel model ) { super( model ); this.highlighter = new DefaultTableCellRenderer(); this.highlighter.setForeground( new Color( 255, 255, 255 ) ); this.highlighter.setBackground( new Color( 0, 0, 128 ) ); } @Override public TableCellRenderer getCellRenderer( final int row, final int column ) { if ( String.valueOf( JCalendar.this.model.getCurrentDate() ).equals( JCalendar.this.model.getValueAt( row, column ) ) && JCalendar.this.model.getCurrentMonth() == JCalendar.this.model.getMonth() && JCalendar.this.model.getCurrentYear() == JCalendar.this.model.getYear() ) { return this.highlighter; } return super.getCellRenderer( row, column ); } } /** * For running this program */ public static void main( final String[] args ) { JCalendar jc = new JCalendar(); JFrame frame = new JFrame( "calendar" ); frame.getContentPane().add( jc ); Dimension frameD = new Dimension( 310, 220 ); Dimension screenD = new Dimension(); screenD = Toolkit.getDefaultToolkit().getScreenSize(); if ( frameD.width >= screenD.width ) { frame.setLocation( 1, 1 ); } frame.setLocation( ( ( screenD.width - frameD.width ) / 2 ), ( ( screenD.height - frameD.height ) / 2 ) ); frame.setSize( frameD.width, frameD.height ); frame.addWindowListener( new WindowAdapter() { @Override public void windowClosing( final WindowEvent e ) { System.exit( 0 ); } } ); frame.setVisible( true ); } }