/* File: DatePanel.java University of Applied Science Berne,HTA-Biel/Bienne, Computer Science Department. Diploma thesis J3D Solar System Simulator Originally written by Marcel Portner & Bernhard Hari (c) 2000 CVS - Information : $Header: /var/cvsreps/projects/c450/2000/sss3d/source_diploma/sss3d/gui/DatePanel.java,v 1.7 2000/12/12 12:01:01 harib Exp $ $Author: harib $ $Date: 2000/12/12 12:01:01 $ $State: Exp $ */ package sss3d.gui; import sss3d.contentbranch.*; import sss3d.utils.xmlparser.*; import sss3d.utils.observer.*; import sss3d.gui.*; import sss3d.utils.SSS3dConstants; import sss3d.calculations.TimeCalc; // converts values between time formats import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.util.*; import javax.swing.event.*; import javax.swing.text.Document; /** * Shows the start settings of the simulator date. * * @author Marcel Portner & Bernhard Hari * @version $Revision: 1.7 $ */ public class DatePanel extends JPanel implements ActionListener, ItemListener, DocumentListener{ private InitializationPanel iniPanel; private ObjectsInformation objInfo; private int parameter = -1; private int mode = SSS3dConstants.RUNTIME_MODE; private JComboBox day; private JComboBox month; private JTextField year; private JComboBox hour; private JComboBox minute; private JComboBox second; private JTextField jday; private JTextPane warning; private JButton button; // variables to check the new date private TimeCalc timeCalculator; private boolean changedJDay = false; private boolean changedGCalendar = false; private boolean update = false; private boolean formatException = false; int dd = 1; // day int mm = 1; // month int yyyy = 2000; // year int hh = 12; // hour int m = 0; // minute int ss = 0; // second double jd = 2451545.0; // julian day private final String [] MONTH_NAMES = { "January","February","March","April","May","June","July", "August","September","October","November","December" }; int[] daysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; /** * Creates a DatePanel. * * @param iniPanel an object reference to an instance of InitializationPanel */ public DatePanel( InitializationPanel iniPanel ) { super(); this.iniPanel = iniPanel; this.mode = iniPanel.getMode(); objInfo = iniPanel.getObjectsInformation(); initialize(); } /** * Creates a DatePanel. * * @param objInfo an object reference to an instance of ObjectsInformation */ public DatePanel( ObjectsInformation objInfo ) { super(); this.objInfo = objInfo; initialize(); } /** * Builds the GUI */ public void initialize( ) { timeCalculator = new TimeCalc(); // create GUI setLayout( new BoxLayout( this, BoxLayout.Y_AXIS ) ); JLabel date = new JLabel("date"); date.setAlignmentX(LEFT_ALIGNMENT); add(date); JPanel valuesPanel = new JPanel(); valuesPanel.setAlignmentX(LEFT_ALIGNMENT); valuesPanel.setBorder(BorderFactory.createEmptyBorder(10,0,10,0)); if ( iniPanel != null ) { valuesPanel.setLayout( new GridLayout( 7,2 ) ); } else { valuesPanel.setLayout( new GridLayout( 14, 1) ); } valuesPanel.add( new JLabel(XMLConstants.treeElementNames[XMLConstants.DAY]) ); day = new JComboBox( createLabels(1,31) ); int value = ((Integer)objInfo.getParameter(XMLConstants.DAY)).intValue(); dd = value; day.setSelectedIndex(value - 1); // index starts at 0 day.addItemListener(this); valuesPanel.add(day); valuesPanel.add( new JLabel(XMLConstants.treeElementNames[XMLConstants.MONTH]) ); month = new JComboBox( MONTH_NAMES ); value = ((Integer)objInfo.getParameter(XMLConstants.MONTH)).intValue(); mm = value; month.setSelectedIndex(value - 1); // index starts at 0 month.addItemListener(this); valuesPanel.add(month); valuesPanel.add( new JLabel(XMLConstants.treeElementNames[XMLConstants.YEAR]) ); year = new JTextField("2000"); value = ((Integer)objInfo.getParameter(XMLConstants.YEAR)).intValue(); yyyy = value; year.setText(Integer.toString(value)); year.getDocument().addDocumentListener(this); year.getDocument().putProperty("name","year"); valuesPanel.add(year); valuesPanel.add( new JLabel(XMLConstants.treeElementNames[XMLConstants.HOUR]) ); hour = new JComboBox( createLabels(0,23) ); value = ((Integer)objInfo.getParameter(XMLConstants.HOUR)).intValue(); hh = value; hour.setSelectedIndex(value); hour.addItemListener(this); valuesPanel.add(hour); valuesPanel.add( new JLabel(XMLConstants.treeElementNames[XMLConstants.MINUTES]) ); minute = new JComboBox( createLabels(0,59) ); value = ((Integer)objInfo.getParameter(XMLConstants.MINUTES)).intValue(); m = value; minute.setSelectedIndex(value); minute.addItemListener(this); valuesPanel.add(minute); valuesPanel.add( new JLabel(XMLConstants.treeElementNames[XMLConstants.SECONDS]) ); second = new JComboBox( createLabels(0,59) ); value = ((Integer)objInfo.getParameter(XMLConstants.SECONDS)).intValue(); ss = value; second.setSelectedIndex(value); second.addItemListener(this); valuesPanel.add(second); valuesPanel.add( new JLabel(XMLConstants.treeElementNames[XMLConstants.JDAY]) ); jday = new JTextField("2451545.0"); Double v = (Double)objInfo.getParameter(XMLConstants.JDAY); jd = v.doubleValue(); jday.setText(v.toString()); jday.getDocument().addDocumentListener(this); jday.getDocument().putProperty("name","jday"); valuesPanel.add(jday); add(valuesPanel); button = new JButton("update"); button.setAlignmentX(LEFT_ALIGNMENT); button.setActionCommand("update"); button.addActionListener(this); add(button); warning = new JTextPane(); warning.setBackground(this.getBackground()); warning.setText(""); warning.setAlignmentX(LEFT_ALIGNMENT); warning.setVisible(true); warning.setEditable(false); add(warning); setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); this.setAlignmentX(LEFT_ALIGNMENT); // enable/disable components depending on they can be changed during // runtime mode switch ( mode ) { case SSS3dConstants.RUNTIME_MODE : day.setEnabled(XMLConstants.MODIFIABLE_VALUES_AT_RUNTIME[XMLConstants.DAY]); month.setEnabled(XMLConstants.MODIFIABLE_VALUES_AT_RUNTIME[XMLConstants.MONTH]); year.setEnabled(XMLConstants.MODIFIABLE_VALUES_AT_RUNTIME[XMLConstants.YEAR]); hour.setEnabled(XMLConstants.MODIFIABLE_VALUES_AT_RUNTIME[XMLConstants.HOUR]); minute.setEnabled(XMLConstants.MODIFIABLE_VALUES_AT_RUNTIME[XMLConstants.MINUTES]); second.setEnabled(XMLConstants.MODIFIABLE_VALUES_AT_RUNTIME[XMLConstants.SECONDS]); jday.setEnabled(XMLConstants.MODIFIABLE_VALUES_AT_RUNTIME[XMLConstants.JDAY]); break; default : break; } this.setVisible(true); } /** * Method to create the labels (numbers) of the JComboBoxes * * @param min the smallest selectable value * @param max the bigest selectable value */ private String[] createLabels( int min, int max ) { int offset = 0; if( min == 0 ) offset = 1; if( min > 1 ) offset = (- min) + 1 ; String labels[] = new String[max + offset]; for ( int i = min; i <= max; i++) { labels[ i - min ] = new String(Integer.toString(i)); } return labels; } /** * Checks if day, month , and year are correct. * Makes checks on leapyear, month february and century. * * @ returns boolean true if given date is valid */ private boolean checkGregorianDay() { boolean correct = false; if ( mm > 0 && mm <= 12 ) { if ( mm == 2 ) { // checks if month is equal to February if ( dd > 0 && dd <= 29 ) { if ( dd == 29 ) { if ( yyyy % 4 == 0 ) { // should be always true if ( yyyy % 400 == 0) { correct = true; } else { if ( yyyy % 100 == 0 ) { //vallid = false; } else { correct = true; } } } // else yyyy isn't a leapyear 29. February isnt' correct } else { correct = true; } } } else { // for January, March, April, May, June, July, August, September, // October, November and December do... int maxDays = daysInMonth[ mm -1 ]; if ( dd > 0 && dd <= maxDays ) { correct = true; } } } return correct; } /** * Checks if entered days are correct * * @return boolean true if values are correct */ private boolean checkValues() { boolean valid = false; if ( formatException ) { year.setText(Integer.toString(yyyy)); jday.setText(Double.toString(jd)); warning.setText("Value automatically reseted !"); formatException = false; } else if( changedGCalendar ) { // user changed only values inside GCalendar if ( checkGregorianDay() ) { jd = timeCalculator.mjd(yyyy, mm, dd, hh, m, ss); jd = jd + 2400000.5; jday.setText( new Double(jd).toString() ); valid = true; }else { warning.setText("Entered values are not valid !"); } } else if ( changedJDay ) { // user changed julian day jd = ( new Double(jday.getText()) ).doubleValue(); double j = jd - 2400000.5; int calendar[] = timeCalculator.calDat(j); year.setText( Integer.toString(calendar[0]) ) ; // year month.setSelectedIndex( calendar[1] - 1 ) ; // month day.setSelectedIndex( calendar[2] - 1) ; // day hour.setSelectedIndex( calendar[3] ) ; // hour minute.setSelectedIndex( calendar[4] ) ; // minute second.setSelectedIndex( calendar[5] ) ; // second valid = true; } else if ( update ) { if ( checkGregorianDay() ) { jd = timeCalculator.mjd(yyyy, mm, dd, hh, m, ss); jd = jd + 2400000.5; jday.setText( new Double(jd).toString() ); valid = true; }else { warning.setText("Entered values are not valid !"); } } if( valid )warning.setText(""); return valid; } public void update() { int value = ((Integer)objInfo.getParameter(XMLConstants.DAY)).intValue(); day.setSelectedIndex(value - 1); // index starts at 0 value = ((Integer)objInfo.getParameter(XMLConstants.MONTH)).intValue(); month.setSelectedIndex(value - 1); // index starts at 0 value = ((Integer)objInfo.getParameter(XMLConstants.YEAR)).intValue(); year.setText(Integer.toString(value)); value = ((Integer)objInfo.getParameter(XMLConstants.HOUR)).intValue(); hour.setSelectedIndex(value); value = ((Integer)objInfo.getParameter(XMLConstants.MINUTES)).intValue(); minute.setSelectedIndex(value); value = ((Integer)objInfo.getParameter(XMLConstants.SECONDS)).intValue(); second.setSelectedIndex(value); Double v = (Double)objInfo.getParameter(XMLConstants.JDAY); jday.setText(v.toString()); } /** * Implementation of action listener. * Called if user pushes the update button. * * @param e java.awt.event.ActionEvent */ public void actionPerformed(java.awt.event.ActionEvent e) { if (e.getActionCommand().equals("update")) { try { //System.out.println("Pushed update button : "+dd+":"+mm+":"+yyyy+":"+hh+":"+m+":"+ss+":"+jd); update = true; // first check if entered values are correct if ( checkValues() ) { if ( mode == SSS3dConstants.INITIALIZATION_MODE || ( mode == SSS3dConstants.RUNTIME_MODE && XMLConstants.MODIFIABLE_VALUES_AT_RUNTIME[XMLConstants.DAY]) ) { objInfo.setParameter(new Integer(dd),XMLConstants.DAY); if( iniPanel != null )iniPanel.updateTreeViewInfo( new Integer(dd),XMLConstants.DAY ); } if ( mode == SSS3dConstants.INITIALIZATION_MODE || ( mode == SSS3dConstants.RUNTIME_MODE && XMLConstants.MODIFIABLE_VALUES_AT_RUNTIME[XMLConstants.MONTH]) ) { objInfo.setParameter(new Integer(mm),XMLConstants.MONTH); if( iniPanel != null )iniPanel.updateTreeViewInfo( new Integer(mm),XMLConstants.MONTH ); } if ( mode == SSS3dConstants.INITIALIZATION_MODE || ( mode == SSS3dConstants.RUNTIME_MODE && XMLConstants.MODIFIABLE_VALUES_AT_RUNTIME[XMLConstants.YEAR]) ) { objInfo.setParameter(new Integer(yyyy),XMLConstants.YEAR); if( iniPanel != null )iniPanel.updateTreeViewInfo( new Integer(yyyy),XMLConstants.YEAR ); } if ( mode == SSS3dConstants.INITIALIZATION_MODE || ( mode == SSS3dConstants.RUNTIME_MODE && XMLConstants.MODIFIABLE_VALUES_AT_RUNTIME[XMLConstants.HOUR]) ) { objInfo.setParameter(new Integer(hh),XMLConstants.HOUR); if( iniPanel != null )iniPanel.updateTreeViewInfo( new Integer(hh),XMLConstants.HOUR ); } if ( mode == SSS3dConstants.INITIALIZATION_MODE || ( mode == SSS3dConstants.RUNTIME_MODE && XMLConstants.MODIFIABLE_VALUES_AT_RUNTIME[XMLConstants.MINUTES]) ) { if( iniPanel != null )iniPanel.updateTreeViewInfo( new Integer(m),XMLConstants.MINUTES ); objInfo.setParameter(new Integer(m),XMLConstants.MINUTES); } if ( mode == SSS3dConstants.INITIALIZATION_MODE || ( mode == SSS3dConstants.RUNTIME_MODE && XMLConstants.MODIFIABLE_VALUES_AT_RUNTIME[XMLConstants.SECONDS]) ) { if( iniPanel != null )iniPanel.updateTreeViewInfo( new Integer(ss),XMLConstants.SECONDS ); objInfo.setParameter(new Integer(ss),XMLConstants.SECONDS); } if ( mode == SSS3dConstants.INITIALIZATION_MODE || ( mode == SSS3dConstants.RUNTIME_MODE && XMLConstants.MODIFIABLE_VALUES_AT_RUNTIME[XMLConstants.JDAY]) ) { if( iniPanel != null )iniPanel.updateTreeViewInfo( new Double(jd),XMLConstants.JDAY ); objInfo.setParameter(new Double(jd),XMLConstants.JDAY); } } } catch(NumberFormatException nfe) { warning.setText("Input is not a Number !!!"); } changedJDay = false; changedGCalendar = false; update = false; } } /** * Listens to diffrent input components. * It checks the entered values if they are correct. * * @param e an instance of ItemEvent */ public void itemStateChanged(ItemEvent e) { Object source = e.getItemSelectable(); if ( day.hasFocus() || month.hasFocus() || hour.hasFocus() || minute.hasFocus() || second.hasFocus() ) { if (source == day || source == month || source == hour || source == minute || source == second ) { // set values dd = day.getSelectedIndex() + 1; mm = month.getSelectedIndex() + 1; hh = hour.getSelectedIndex(); m = minute.getSelectedIndex(); ss = second.getSelectedIndex(); changedGCalendar = true; changedJDay = false; checkValues(); changedGCalendar = false; } } } /** * DocumentListener - this method is called if user adds chars to text input field. * * @param e an instance of DocumentEvent */ public void insertUpdate(DocumentEvent e) { Document doc = e.getDocument(); if (doc.getProperty("name").equals("year")) { if ( year.hasFocus() ) { // set new value try { yyyy = (new Integer(year.getText())).intValue(); changedGCalendar = true; changedJDay = false; checkValues(); changedGCalendar = false; } catch(IllegalStateException exception) { // it's a work around a problem } catch(NumberFormatException nfe) { warning.setText("Year is not an integer value !"); //year.setText(Integer.toString(yyyy)); // is not possible during event handling formatException = true; } } } else if (doc.getProperty("name").equals("jday")) { if ( jday.hasFocus() ) { // set new value try { jd = ( new Double(jday.getText()) ).doubleValue(); changedJDay = true; changedGCalendar = false; checkValues(); changedJDay = false; } catch(IllegalStateException exception) { } catch(NumberFormatException nfe) { warning.setText("Julian Day is not a floating point value !"); //jday.setText(Double.toString(jd)); // is not possible during event handling formatException = true; } } } } /** * DocumentListener - not used at the moment */ public void removeUpdate(DocumentEvent e) { } /** * DocumentListener - not used at the moment */ public void changedUpdate(DocumentEvent e) { } }