package caltool.view.schedule; import caltool.model.schedule.*; import caltool.view.*; import mvp.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; /**** * * Class ScheduleEventDialog provides a view of Event as an input to the * scheduleEvent method. Hence, the dialog is a view of both an Event object * as well as the scheduleEvent method. The data-entry components of the * dialog constitute the Event view. The 'OK' button is the view of the * scheduleEvent method. *

* The data components consist of JLabels, JTextFields, and a JComboBox. The * 'OK', 'Clear', and 'Cancel' buttons are JButtons. The description of the compose method has details of how the components * are laid out in the dialog window. *

* The companion model for ScheduleEventDialog is the * Schedule class, since Schedule has the method that is invoked from the * 'OK' button action listener. See class OKScheduleEventButtonListener.html for * details of how the Schedule.scheduleEvent method is invoked. * * @author Gene Fisher (gfisher@calpoly.edu) * @version 6feb04 * */ public class ScheduleEventDialog extends CalendarToolWindow { /** * Construct this with the given Schedule as companion model. */ public ScheduleEventDialog(Screen screen, Schedule schedule, CalendarToolUI calToolUI) { /* * Call the parent constructor. */ super(screen, schedule, calToolUI); /* * Set the maximum component height and width. These the height value * was empiricaly derived, i.e., I fiddled around with it while looking * at the display. The width value is presumably as big as the biggest * screen we'll come across. If not, deal with it. */ maxComponentHeight = 1.9; maxComponentWidth = 2000; } /** * Compose this as a vertical Box of four rows. Each row is a horizontal * Box. The first row contains a labeled text field for the event title. * The second row has labeled text fields for the start and end dates. The * third row has a labeled combo box for the category selection and a * labeled combol box for the event security. Finally, the fourth row has * the 'OK', 'Clear', and 'Cancel' buttons. *

* Vertical and horizontal struts are used for spacing among all of the * components. */ public Component compose() { /* * Add a JPanel to this' window, which was created in the parent class' * constructor. JPanel is the standard background container for * holding Swing components. */ panel = new JPanel(); window.add(panel); /* * Set the layout style of the panel to be a vertical box. */ panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); /* * Compose each of the rows and add to the vertically laid out panel. * Put some spacing between each row, in the form of a vertical strut. */ panel.add(Box.createVerticalStrut(15)); panel.add(composeTitleRow()); panel.add(Box.createVerticalStrut(15)); panel.add(composeStartAndEndDateRow()); panel.add(Box.createVerticalStrut(15)); panel.add(composeCategoryAndSecurityRow()); panel.add(Box.createVerticalStrut(25)); panel.add(composeButtonRow()); panel.add(Box.createVerticalStrut(15)); /* * Set the window titlebar. */ window.setTitle("Schedule an Event"); /* * Call JFrame.pack to have Java size up the window properly. */ window.pack(); /* * Return the window to the caller. */ return window; } /*-* * Data collection methods. */ /** * Return the title as a string. */ public String getTitle() { return titleTextField.getText(); } /** * Return the start date as a Date value. Note that the Date model class * does the parsing. */ public Date getStartDate() { return new Date(startDateTextField.getText()); } /** * Return the end date as a Date value. Note that the Date model class * does the parsing. */ public Date getEndDate() { return new Date(startDateTextField.getText()); } /** * Return selected category as a Category value. * does the parsing. */ public Category getCategory() { return new Category((String) categoryComboBox.getSelectedItem()); } /** * Return the security as a simple security value. */ public SimpleSecurity getSecurity() { return SimpleSecurity.valueOf( (String) securityComboBox.getSelectedItem()); } /** * Display the error messages in the given exception object in a modal * pop-up window. */ public void displayErrors(ScheduleEventPrecondViolation errors) { int i; // Error array loop index /* * Stubbed out implementation to std err instead of pop-up window. */ for (i = 0; i < errors.numberOfErrors(); i++) { System.err.println(errors.getErrors()[i]); } } /** * Compose the title row using a JLabel and JTextField. */ protected Box composeTitleRow() { Box hbox = Box.createHorizontalBox(); /* * Construct the label and text field. */ JLabel label = new JLabel("Title: "); titleTextField = new JTextField(); /* * Set the label font color to black, since I don't care for the * default "Java blue". */ label.setForeground(Color.black); /* * Set the max height of the text field to keep it from resizing * vertically in the vertical box layout of the panel. */ titleTextField.setMaximumSize( new Dimension(maxComponentWidth, (int)(maxComponentHeight * titleTextField.getFont().getSize()))); /* * Add the label and text field to the hbox and return it. Use * horizontal struts for spacing. */ hbox.add(Box.createHorizontalStrut(15)); hbox.add(label); hbox.add(titleTextField); titleTextField.setAlignmentX(Component.RIGHT_ALIGNMENT); hbox.add(Box.createHorizontalStrut(15)); return hbox; } /** * Compose the start/end date row using two pairs of JLabel and JTextField. */ protected Box composeStartAndEndDateRow() { Box hbox = Box.createHorizontalBox(); /* * Construct the labels and text fields. See internal comments in the * composeTitle method for further explanatory details. */ JLabel startLabel = new JLabel("Start Date: "); startLabel.setForeground(Color.black); startDateTextField = new JTextField(15); startDateTextField.setMaximumSize( new Dimension(maxComponentWidth, (int)(maxComponentHeight * startDateTextField.getFont().getSize()))); JLabel endLabel = new JLabel("End Date: "); endLabel.setForeground(Color.black); endDateTextField = new JTextField(15); endDateTextField.setMaximumSize( new Dimension(maxComponentWidth, (int)(maxComponentHeight * startDateTextField.getFont().getSize()))); /* * Add them to the hbox and return it. */ hbox.add(Box.createHorizontalStrut(15)); hbox.add(startLabel); hbox.add(startDateTextField); hbox.add(Box.createHorizontalStrut(10)); hbox.add(endLabel); hbox.add(endDateTextField); hbox.add(Box.createHorizontalStrut(15)); return hbox; } /** * Compose the category/security row using a JComboBox and JTextField, with * JLabels next to each. */ protected Box composeCategoryAndSecurityRow() { Box hbox = Box.createHorizontalBox(); /* * Construct the labels and text fields. See internal comments in the * composeTitle method for further explanatory details. */ JLabel categoryLabel = new JLabel("Category: "); categoryLabel.setForeground(Color.black); categoryComboBox = new JComboBox(); categoryComboBox.addItem("none"); JLabel securityLabel = new JLabel("Security: "); securityLabel.setForeground(Color.black); String[] selections = {"Public", "Private"}; securityComboBox = new JComboBox(selections); /* * Add them to the hbox and return it. */ hbox.add(Box.createHorizontalStrut(15)); hbox.add(categoryLabel); hbox.add(categoryComboBox); hbox.add(Box.createHorizontalStrut(10)); hbox.add(securityLabel); hbox.add(securityComboBox); hbox.add(Box.createHorizontalStrut(15)); return hbox; } /** * Compose the buttons row with three JButtons. The action listeners for * Clear and Cancel buttons are straightforward. The action listener for * the OK button is responsible for communication with the Schedule model. * See the description of for explanatory details. * */ protected Box composeButtonRow() { Box hbox = Box.createHorizontalBox(); /* * Construct the three buttons. */ JButton okButton = new JButton("OK"); JButton clearButton = new JButton("Clear"); JButton cancelButton = new JButton("Cancel"); /* * Attach the appropriate action listeners to each button. */ okButton.addActionListener( new OKScheduleEventButtonListener((Schedule) model, this)); clearButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { clear(); } } ); cancelButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { hide(); } } ); /* * Add them to the hbox and return it. */ hbox.add(okButton); hbox.add(Box.createHorizontalStrut(30)); hbox.add(clearButton); hbox.add(Box.createHorizontalStrut(30)); hbox.add(cancelButton); return hbox; } /** * Clear each of the text fields of this to empty. Reset the combo box to * no selection. NOTE: This method needs to be refined to use default * values for clearing, once options and defaults functionality is * implemented. */ protected void clear() { titleTextField.setText(""); startDateTextField.setText(""); endDateTextField.setText(""); categoryComboBox.setSelectedIndex(0); securityComboBox.setSelectedIndex(0); } /** The background panel of this */ protected JPanel panel; /** The title text field */ protected JTextField titleTextField; /** The start date text field */ protected JTextField startDateTextField; /** The end date text field */ protected JTextField endDateTextField; /** The Categories combo box */ protected JComboBox categoryComboBox; /** The security text field */ protected JComboBox securityComboBox; /** The max height of a text field or combobox; this is necessary since these components stretch when the outer frame is resized, and look very funky when they do. */ protected final double maxComponentHeight; /** The max width of any component; this is only necessary because the max height cannot be set separately, so we must pick some max width. */ protected final int maxComponentWidth; }