|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.tasklist.usertasks; import java.awt.Color; import java.awt.Component; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import org.openide.explorer.propertysheet.editors.EnhancedCustomPropertyEditor; /** * This is a small panel to allow the user to select a full date. When I * started the implementation of the Alarm functionality I had the user to * write the complete time/date, and I pretty soon realized that noone will * remember the format each time.... Well, the panel "works for me now" so I * move on to the next phase in my project, but one should really: * * @todo The panel is too big... * * @author Trond Norbye */ public class DateSelectionPanel extends javax.swing.JPanel implements EnhancedCustomPropertyEditor { private static final long serialVersionUID = 1; /** * A calendar object I use for varius things (mostly for converting values * to string representation... */ private GregorianCalendar calendar; /** * A SimpleDateFormat I use for conversion to/from textual representation * of date fields */ private SimpleDateFormat format; /** * The tablemodel behind the day-selection table (most of the * "logic" resides inside this class.... */ private DateSelectionTableModel tablemodel; /** * The renderer I use to render the cells in the JTable (I wanted the * day label to be centered, and todays date to be red.... */ private CalendarRenderer renderer; /** Creates new form DateSelectionPanel */ public DateSelectionPanel() { this(new Date()); } /** * Create a new DateSelectionPanel with the given date selected... * * @param date initial selection */ public DateSelectionPanel(Date date) { initComponents(); // The table model will never change, so I might as well store it // here so I don't need to get it each time... tablemodel = (DateSelectionTableModel)calendarTable.getModel(); calendarTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); renderer = new CalendarRenderer(); calendarTable.setDefaultRenderer(String.class, renderer); calendar = new GregorianCalendar(); yearFld.setText(Integer.toString(calendar.get(calendar.YEAR))); format = new SimpleDateFormat("HH:mm:ss"); timeFld.setText(format.format(date)); format.applyPattern("MMMM"); int curr = calendar.get(calendar.MONTH); calendar.set(calendar.MONTH, calendar.getActualMinimum(calendar.MONTH)); int no = calendar.getActualMaximum(calendar.MONTH) - calendar.getActualMinimum(calendar.MONTH); for (int ii = 0; ii <= no; ++ii) { monthNameCmb.insertItemAt(format.format(calendar.getTime()), ii); calendar.roll(calendar.MONTH, 1); } monthNameCmb.setSelectedIndex(curr); calendar.setTime(date); tablemodel.setMonth(calendar.get(calendar.MONTH)); tablemodel.setYear(calendar.get(calendar.YEAR)); tablemodel.setSelectedDay(calendar.get(calendar.DAY_OF_MONTH)); calendarTable.getTableHeader().setReorderingAllowed(false); calendarTable.getTableHeader().setResizingAllowed(false); } /** * Returns the selected date * * @return selected date */ public Date getDate() { Date ret; try { format.applyPattern("HH:mm:ss"); calendar.setTime(format.parse(timeFld.getText())); calendar.set(calendar.MONTH, monthNameCmb.getSelectedIndex()); calendar.set(calendar.YEAR, Integer.parseInt(yearFld.getText())); calendar.set(calendar.DAY_OF_MONTH, tablemodel.getSelectedDay()); ret = calendar.getTime(); } catch (Exception e) { // When I'm done, this should never happen.... ret = null; } return ret; } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ private void initComponents() {//GEN-BEGIN:initComponents jPanel1 = new javax.swing.JPanel(); monthNameCmb = new javax.swing.JComboBox(); prevYearBtn = new javax.swing.JButton(); yearFld = new javax.swing.JTextField(); nextYearBtn = new javax.swing.JButton(); jLabel1 = new javax.swing.JLabel(); timeFld = new javax.swing.JTextField(); jPanel2 = new javax.swing.JPanel(); jScrollPane1 = new javax.swing.JScrollPane(); calendarTable = new javax.swing.JTable(); setLayout(new java.awt.BorderLayout()); setBorder(new javax.swing.border.EmptyBorder(new java.awt.Insets(11, 11, 12, 12))); jPanel1.setBorder(new javax.swing.border.EmptyBorder(new java.awt.Insets(0, 0, 11, 0))); monthNameCmb.setMaximumRowCount(12); monthNameCmb.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { DateSelectionPanel.this.monthNameCmbActionPerformed(evt); } }); jPanel1.add(monthNameCmb); prevYearBtn.setText("<"); prevYearBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { DateSelectionPanel.this.prevYearBtnActionPerformed(evt); } }); jPanel1.add(prevYearBtn); yearFld.setColumns(4); yearFld.setHorizontalAlignment(javax.swing.JTextField.CENTER); yearFld.setInputVerifier(new javax.swing.InputVerifier() { public boolean verify(javax.swing.JComponent obj) { boolean ret; try { Integer.parseInt(((javax.swing.JTextField)obj).getText()); ret = true; } catch (Exception e) { ret = false; } return ret; } }); yearFld.addFocusListener(new java.awt.event.FocusAdapter() { public void focusLost(java.awt.event.FocusEvent evt) { DateSelectionPanel.this.yearFldFocusLost(evt); } }); jPanel1.add(yearFld); nextYearBtn.setText(">"); nextYearBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { DateSelectionPanel.this.nextYearBtnActionPerformed(evt); } }); jPanel1.add(nextYearBtn); jLabel1.setText("@"); jPanel1.add(jLabel1); timeFld.setColumns(8); timeFld.setHorizontalAlignment(javax.swing.JTextField.CENTER); timeFld.setInputVerifier(new javax.swing.InputVerifier() { public boolean verify(javax.swing.JComponent obj) { boolean ret; try { format.applyPattern("HH:mm:ss"); format.parse(((javax.swing.JTextField)obj).getText()); ret = true; } catch (Exception e) { ret = false; } return ret; } }); jPanel1.add(timeFld); add(jPanel1, java.awt.BorderLayout.NORTH); jPanel2.setLayout(new java.awt.GridLayout(1, 1)); calendarTable.setModel(new DateSelectionTableModel()); calendarTable.setCellSelectionEnabled(true); calendarTable.setPreferredScrollableViewportSize(new java.awt.Dimension(450, 150)); calendarTable.setShowHorizontalLines(false); calendarTable.setShowVerticalLines(false); jScrollPane1.setViewportView(calendarTable); jPanel2.add(jScrollPane1); add(jPanel2, java.awt.BorderLayout.CENTER); }//GEN-END:initComponents /** * This is probably not the "correct" place to do this, but it works as * intended... * @param evt not used */ private void yearFldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_yearFldFocusLost int year = Integer.parseInt(yearFld.getText()); tablemodel.setYear(year); }//GEN-LAST:event_yearFldFocusLost /** * The user pressed the "<" button.. The year field should be decremented * @param evt the event */ private void prevYearBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_prevYearBtnActionPerformed if (evt.getID() == evt.ACTION_PERFORMED) { int year = Integer.parseInt(yearFld.getText()) - 1; yearFld.setText(Integer.toString(year)); tablemodel.setYear(year); } }//GEN-LAST:event_prevYearBtnActionPerformed /** * The user pressed the ">" button.. The year field should be incremented * @param evt the event */ private void nextYearBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nextYearBtnActionPerformed if (evt.getID() == evt.ACTION_PERFORMED) { int year = Integer.parseInt(yearFld.getText()) + 1; yearFld.setText(Integer.toString(year)); tablemodel.setYear(year); } }//GEN-LAST:event_nextYearBtnActionPerformed /** * The user changed the month combo.. * @param evt not used */ private void monthNameCmbActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_monthNameCmbActionPerformed if (evt.getID() == evt.ACTION_PERFORMED) { tablemodel.setMonth(monthNameCmb.getSelectedIndex()); } }//GEN-LAST:event_monthNameCmbActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTable calendarTable; private javax.swing.JLabel jLabel1; private javax.swing.JTextField timeFld; private javax.swing.JButton prevYearBtn; private javax.swing.JPanel jPanel2; private javax.swing.JTextField yearFld; private javax.swing.JComboBox monthNameCmb; private javax.swing.JPanel jPanel1; private javax.swing.JButton nextYearBtn; // End of variables declaration//GEN-END:variables /** * An inner class used by the table */ private class DateSelectionTableModel extends AbstractTableModel { private static final long serialVersionUID = 1; private Object columnNames[]; private GregorianCalendar calendar, today; private Integer days[][]; /** * Create a new table model */ public DateSelectionTableModel() { columnNames = new Object[7]; calendar = new GregorianCalendar(); SimpleDateFormat format = new SimpleDateFormat("EEEE"); calendar.set(calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek()); for (int ii = 0; ii < 7; ++ii) { columnNames[ii] = format.format(calendar.getTime()); calendar.roll(calendar.DAY_OF_WEEK, 1); } today = new GregorianCalendar(); // Reset the calendar since I might have changed the current month calendar.setTime(new Date()); days = new Integer[6][7]; } /** * Set a day in the month as selected * @param the day to select */ void setSelectedDay(int day) { for (int yy = 0; yy < days.length; ++yy) { for (int xx = 0; xx < days[yy].length; ++xx) { if (days[yy][xx] != null) { Integer i = (Integer)days[yy][xx]; if (i.intValue() == day){ calendarTable.changeSelection(yy, xx, false, false); return; } } } } } /** * Get the currently selected day (or the first / last day of the * month if a blank field (or none) was selected * @return the selected day */ public int getSelectedDay() { int x = calendarTable.getSelectedColumn(); int y = calendarTable.getSelectedRow(); int retval; if (x == -1 || y == -1) { retval = 1; } else if (days[y][x] != null) { retval = ((Integer)days[y][x]).intValue(); } else { if (y == 0) { retval = calendar.getActualMinimum(calendar.DAY_OF_MONTH); } else { retval = calendar.getActualMaximum(calendar.DAY_OF_MONTH); } } return retval; } /** * Lay out all of the day number correctly */ public void updateDays() { calendar.set(calendar.DAY_OF_MONTH, calendar.getActualMinimum(calendar.DAY_OF_MONTH)); int day = getSelectedDay(); if (calendar.get(calendar.MONTH) == today.get(today.MONTH) && calendar.get(calendar.YEAR) == today.get(today.YEAR)) { renderer.setToday(new Integer(today.get(today.DAY_OF_MONTH))); } else { renderer.setToday(null); } int start = calendar.get(calendar.DAY_OF_WEEK) - calendar.getFirstDayOfWeek(); if (start < 0) { start += 7; } // Reset the data: for (int i = 0; i < days.length; ++i) { for (int j = 0; j < days[i].length; ++j) { days[i][j] = null; } } int x = start, y = 0; int noDays = calendar.getActualMaximum(calendar.DAY_OF_MONTH); for (int i = calendar.getActualMinimum(calendar.DAY_OF_MONTH); i <= noDays; ++i) { days[y][x] = new Integer(i); ++x; if (x == 7) { x = 0; ++y; } } fireTableDataChanged(); setSelectedDay(day); } /** * Set the current month * @param month the new month */ public void setMonth(int month) { if (month >= calendar.getActualMinimum(calendar.MONTH) && month <= calendar.getActualMaximum(calendar.MONTH)) { calendar.set(calendar.MONTH, month); updateDays(); } } /** * Set the current year * @param year the new year */ public void setYear(int year) { if (year >= calendar.getActualMinimum(calendar.YEAR) && year <= calendar.getActualMaximum(calendar.YEAR)) { calendar.set(calendar.YEAR, year); updateDays(); } } /** * Get the name of the column.. * @param col The column to get the name for * @return The column name */ public String getColumnName(int col) { return columnNames[col].toString(); } /** * Get the total number of elements in the data model * @return the number of elements... */ public int getRowCount() { return 6; } /** * Get the number of columns * @return the number of columns */ public int getColumnCount() { return columnNames.length; } /** * Get the value stored at a given position inside the table * @param row the row number * @param col the column number * @return the object stored at [row,col] */ public Object getValueAt(int row, int col) { return days[row][col]; } /** * Is a given cell editable? * @param row the row number * @param col the column number * @return true if the cell can be edited, false otherwise */ public boolean isCellEditable(int row, int col) { return false; } /** * Get the object class used in a column * @param c the column number * @return Boolean for column 0, string otherwise... */ public Class getColumnClass(int c) { return String.class; } } /** * A small little renderer so I can get the text centered, and todays day * in red... */ private static class CalendarRenderer extends DefaultTableCellRenderer { private static final long serialVersionUID = 1; private Integer today; private Color defaultColor; /** Create a new CalendarRenderer */ public CalendarRenderer() { super(); defaultColor = getForeground(); } /** * Set todays day number * @param today or null to turn off */ public void setToday(Integer today) { this.today = today; } /** * Get the Cell renderer */ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (today != null && today.equals(value)) { setForeground(Color.red); } else { setForeground(defaultColor); } setHorizontalAlignment( javax.swing.SwingConstants.CENTER); return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); } } // When used as a property customizer public Object getPropertyValue() throws IllegalStateException { return getDate(); } /** * A "main method" if you would like to test the panel... * @param argv not used */ // public static void main(String argv[]) { // javax.swing.JFrame frm = new javax.swing.JFrame(); // frm.getContentPane().add(new DateSelectionPanel()); // frm.pack(); // frm.setVisible(true); // frm.addWindowListener(new java.awt.event.WindowAdapter() { // public void windowClosing(java.awt.event.WindowEvent e) { // System.exit(0); // } // }); // } public static void test() throws Exception { javax.swing.JFrame frm = new javax.swing.JFrame(); DateSelectionPanel panel = new DateSelectionPanel(); frm.getContentPane().add(panel); frm.pack(); frm.setVisible(true); frm.addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent e) { System.exit(0); } }); Calendar c = new GregorianCalendar(); for (int cntr = 1900; cntr < 3000; cntr++) { c.set(Calendar.YEAR, cntr); for (int cntrX = c.getActualMinimum(Calendar.MONTH); cntrX < c.getActualMaximum(Calendar.MONTH); cntrX++) { panel.tablemodel.setYear(cntr); panel.tablemodel.setMonth(cntrX); c.set(Calendar.MONTH, cntrX); c.set(Calendar.DAY_OF_MONTH, panel.tablemodel.days[1][0].intValue()); if (c.get(Calendar.DAY_OF_WEEK) != c.getFirstDayOfWeek()) { System.err.println("The assignment of day of week is incorrect for year: " + c.get(Calendar.YEAR) + " and month: " + c.get(Calendar.MONTH)); } } } } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.